Skip to content

Commit

Permalink
Merge pull request #960 from postmanlabs/feature/response-stream-base64
Browse files Browse the repository at this point in the history
Accept Response.stream to be a Base64 string
  • Loading branch information
codenirvana committed Dec 2, 2019
2 parents ae96550 + be26bc6 commit dfb321d
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 11 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
master:
chores:
- GH-960 Accept Response.stream to be a Base64 string
fixed bugs:
- >
GH-958 Fixed a bug where special characters in proxy auth credentials
Expand Down
58 changes: 47 additions & 11 deletions lib/collection/response.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,21 @@ var util = require('../util'),
* @const
* @type {string}
*/
BUFFER = 'Buffer',
BASE64 = 'base64',

/**
* @private
* @const
* @type {string}
*/
STREAM_TYPE_BUFFER = 'Buffer',

/**
* @private
* @const
* @type {string}
*/
STREAM_TYPE_BASE64 = 'Base64',

/**
* @private
Expand All @@ -90,6 +104,13 @@ var util = require('../util'),
*/
FUNCTION = 'function',

/**
* @private
* @const
* @type {string}
*/
STRING = 'string',

/**
* @private
* @const
Expand Down Expand Up @@ -142,17 +163,27 @@ var util = require('../util'),
supportsBuffer = (typeof Buffer !== undefined) && _.isFunction(Buffer.byteLength),

/**
* Normalises an input Buffer or buffer.toJSON() into a Buffer or ArrayBuffer.
* Normalizes an input Buffer, Buffer.toJSON() or base64 string into a Buffer or ArrayBuffer.
*
* @private
* @param {Buffer|Object} stream - An instance of Buffer of an object representation of Buffer(Buffer.toJSON())
* @param {Buffer|Object} stream - An instance of Buffer, Buffer.toJSON(), or Base64 string
* @returns {Buffer|ArrayBuffer|undefined}
*/
normaliseStream = function (stream) {
if (stream && stream.type === BUFFER && _.isArray(stream.data)) {
normalizeStream = function (stream) {
if (!stream) { return; }

// create buffer from buffer's JSON representation
if (stream.type === STREAM_TYPE_BUFFER && _.isArray(stream.data)) {
// @todo Add tests for Browser environments, where ArrayBuffer is returned instead of Buffer
return typeof Buffer === FUNCTION ? new Buffer(stream.data) : new Uint8Array(stream.data).buffer;
return typeof Buffer === FUNCTION ? Buffer.from(stream.data) : new Uint8Array(stream.data).buffer;
}

// create buffer from base64 string
if (stream.type === STREAM_TYPE_BASE64 && typeof stream.data === STRING) {
return Buffer.from(stream.data, BASE64);
}

// probably it's already of type buffer
return stream;
},

Expand Down Expand Up @@ -189,8 +220,9 @@ _.inherit((

_.assign(Response.prototype, /** @lends Response.prototype */ {
update: function (options) {
// options.stream accepts new Buffer() as well as new Buffer().toJSON()
var stream = normaliseStream(options.stream);
// options.stream accepts Buffer, Buffer.toJSON() or base64 string
// @todo this temporarily doubles the memory footprint (options.stream + generated buffer).
var stream = normalizeStream(options.stream);

_.mergeDefined((this._details = _.clone(httpReasons.lookup(options.code))), {
name: _.choose(options.reason, options.status),
Expand Down Expand Up @@ -230,8 +262,7 @@ _.assign(Response.prototype, /** @lends Response.prototype */ {
*
* @type {Buffer|UInt8Array}
*/
stream: options.body && !_.isString(options.body) && _.isObject(options.body) ?
options.body : stream,
stream: (options.body && _.isObject(options.body)) ? options.body : stream,

/**
* @type {CookieList}
Expand Down Expand Up @@ -263,11 +294,16 @@ _.assign(Response.prototype, /** @lends Response.prototype */ {
_postman_propertyRequiresId: true,

/**
* Convert this response into a JSON serialisable object. The _details meta property is omitted.
* Convert this response into a JSON serializable object. The _details meta property is omitted.
*
* @returns {Object}
*
* @todo consider switching to a different response buffer (stream) representation in v4 as Buffer.toJSON
* appears to cause multiple performance issues.
*/
toJSON: function () {
// @todo benchmark PropertyBase.toJSON, response Buffer.toJSON or _.cloneElement might
// be the bottleneck.
var response = PropertyBase.toJSON(this);

response._details && (delete response._details);
Expand Down
14 changes: 14 additions & 0 deletions test/unit/response.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,20 @@ describe('Response', function () {
global.Buffer = originalBuffer;
});

it('should handle base64 response stream', function () {
var buffer = Buffer.from('Postman'),
response = new Response({
stream: {
type: 'Base64',
data: buffer.toString('base64')
}
});

expect(response.toJSON()).to.have.property('stream')
.that.eql(buffer.toJSON());
expect(response.text()).to.equal('Postman');
});

it('should handle non atomic bodies correctly', function () {
var response = new Response({ body: { foo: 'bar' } });

Expand Down

0 comments on commit dfb321d

Please sign in to comment.