Skip to content

Commit

Permalink
Added attributes to size function to track transfer size and resource…
Browse files Browse the repository at this point in the history
… size
  • Loading branch information
parthverma1 committed Jun 26, 2024
1 parent 354823f commit 71cb1e3
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 41 deletions.
74 changes: 45 additions & 29 deletions lib/collection/response.js
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,7 @@ _.assign(Response.prototype, /** @lends Response.prototype */ {
var response = PropertyBase.toJSON(this);

response._details && (delete response._details);
delete response.downloadedBytes;

return response;
},
Expand Down Expand Up @@ -409,46 +410,61 @@ _.assign(Response.prototype, /** @lends Response.prototype */ {
*/
size: function () {
var sizeInfo = {
body: this.downloadedBytes || 0,
body: 0,
header: 0,
total: 0
total: 0,
transferedBytes: this.downloadedBytes || 0,
resourceBytes: 0
},
contentEncoding = this.headers.get(CONTENT_ENCODING),
contentLength = this.headers.get(CONTENT_LENGTH),
isCompressed = false,
byteLength;

if (!this.downloadedBytes) {
if (_.isString(contentEncoding)) {
// desensitise case of content encoding
contentEncoding = contentEncoding.toLowerCase();
// eslint-disable-next-line lodash/prefer-includes
isCompressed = (contentEncoding.indexOf('gzip') > -1) || (contentEncoding.indexOf('deflate') > -1);
}

// If there is a stream defined which looks like buffer, use it's data to calculate the body
if (this.stream) {
byteLength = this.stream.byteLength;
sizeInfo.body = util.isNumeric(byteLength) ? byteLength :
/* istanbul ignore next */
0;
// if server sent encoded data, we should first try deriving length from headers
if (_.isString(contentEncoding)) {
// desensitise case of content encoding
contentEncoding = contentEncoding.toLowerCase();
// eslint-disable-next-line lodash/prefer-includes
isCompressed = (contentEncoding.indexOf('gzip') > -1) || (contentEncoding.indexOf('deflate') > -1);
}

// if 'Content-Length' header is present and encoding is of type gzip/deflate, we take body as declared by
// server. else we need to compute the same.
if (contentLength && isCompressed && util.isNumeric(contentLength)) {
sizeInfo.body = _.parseInt(contentLength, 10);
}
// If there is a stream defined which looks like buffer, use it's data to calculate the body

if (this.stream) {
byteLength = this.stream.byteLength;
const streamLength = util.isNumeric(byteLength) ? byteLength :
/* istanbul ignore next */
0;

sizeInfo.resourceBytes = streamLength;

if (!sizeInfo.body) {
sizeInfo.body = streamLength;
}
// otherwise, if body is defined, we try get the true length of the body
else if (!_.isNil(this.body)) {
sizeInfo.body = supportsBuffer ? Buffer.byteLength(this.body.toString()) :
/* istanbul ignore next */
this.body.toString().length;
}
// otherwise, if body is defined, we try get the true length of the body
else if (!_.isNil(this.body)) {
const bodyLength = supportsBuffer ? Buffer.byteLength(this.body.toString()) :
/* istanbul ignore next */
this.body.toString().length;

sizeInfo.resourceBytes = bodyLength;
if (!sizeInfo.body) {
sizeInfo.body = bodyLength;
}
}

if (!sizeInfo.downloadedBytes) {
if (contentLength && isCompressed && util.isNumeric(contentLength)) {
sizeInfo.downloadedBytes = _.parseInt(contentLength, 10);
}
else {
sizeInfo.downloadedBytes = sizeInfo.body;
}
}
if (!sizeInfo.transferedBytes) {
sizeInfo.transferedBytes = sizeInfo.resourceBytes;
}

// size of header is added
// https://tools.ietf.org/html/rfc7230#section-3
// HTTP-message = start-line (request-line / status-line)
Expand All @@ -460,7 +476,7 @@ _.assign(Response.prototype, /** @lends Response.prototype */ {
this.headers.contentSize();

// compute the approximate total body size by adding size of header and body
sizeInfo.total = (sizeInfo.body || 0) + (sizeInfo.header);
sizeInfo.total = (sizeInfo.transferedBytes || 0) + (sizeInfo.header);

return sizeInfo;
},
Expand Down
38 changes: 26 additions & 12 deletions test/unit/response.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -271,16 +271,14 @@ describe('Response', function () {
it('should handle blank responses correctly', function () {
var response = new Response();

expect(response.size()).to.eql({
body: 0, header: 32, total: 32, downloadedBytes: 0
});
expect(response.size()).to.eql({ body: 0, header: 32, total: 32, transferedBytes: 0, resourceBytes: 0 });
});

it('should report downloaded size correctly', function () {
var response = new Response({ body: 'random', downloadedBytes: 6 });
var response = new Response({ body: 'random', transferedBytes: 6 });

expect(response.size()).to.eql({
body: 6, header: 32, total: 38
body: 6, header: 32, total: 38, transferedBytes: 6, resourceBytes: 6
});
});
});
Expand Down Expand Up @@ -459,8 +457,8 @@ describe('Response', function () {
size1 = response1.size(),
size2 = response2.size();

expect(size1.downloadedBytes + size1.header).to.eql(rawResponse1.header.length + rawResponse1.body.length);
expect(size2.downloadedBytes + size2.header).to.eql(rawResponse1.header.length + rawResponse1.body.length);
expect(size1.body + size1.header).to.eql(rawResponse1.header.length + rawResponse1.body.length);
expect(size2.body + size2.header).to.eql(rawResponse1.header.length + rawResponse1.body.length);
});

it('must match the content-length of the response if gzip encoded', function () {
Expand All @@ -471,7 +469,7 @@ describe('Response', function () {
},
response = new Response(rawResponse);

expect(response.size().downloadedBytes).to.equal(10);
expect(response.size().body).to.equal(10);
});

it('must match the content-length of the response if deflate encoded', function () {
Expand All @@ -482,7 +480,7 @@ describe('Response', function () {
},
response = new Response(rawResponse);

expect(response.size().downloadedBytes).to.equal(20);
expect(response.size().body).to.equal(20);
});

it('must use byteLength from buffer if provided', function () {
Expand All @@ -496,16 +494,32 @@ describe('Response', function () {
expect(response.size().body).to.equal(14);
});

it('must use body size if no downloaded bytes are provided', function () {
it('must use downloaded size if provided', function () {
var rawResponse = {
code: 200,
body: 'something nice',
header: 'Transfer-Encoding: chunked'
header: 'Transfer-Encoding: chunked\nContent-Length: 20',
downloadedBytes: 10
},
response = new Response(rawResponse);

expect(response.size().downloadedBytes).to.equal(14);
expect(response.size().body).to.equal(14);
expect(response.size().transferedBytes).to.equal(10);
expect(response.size().resourceBytes).to.equal(14);
});

it('must use content length of stream if header is provided', function () {
var rawResponse = {
code: 200,
stream: Buffer.from('something nice'),
header: 'Transfer-Encoding: chunked\nContent-Length: 20\nContent-Encoding: gzip',
downloadedBytes: 10
},
response = new Response(rawResponse);

expect(response.size().body).to.equal(20);
expect(response.size().transferedBytes).to.equal(10);
expect(response.size().resourceBytes).to.equal(14);
});
});

Expand Down

0 comments on commit 71cb1e3

Please sign in to comment.