Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feature] send blob response #5139

Closed
wants to merge 37 commits into from
Closed
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
c10d281
make changes to response file and add test cases for it
debadutta98 Mar 4, 2023
3671e28
run all test case against res.send successfully total testcase 1264 p…
debadutta98 Mar 4, 2023
9ca3e7b
add type checking
debadutta98 Mar 5, 2023
e96788c
fix code for v14.0.0 and v15.0.0
debadutta98 Mar 5, 2023
5a8908a
update test cases
debadutta98 Mar 5, 2023
8805aa8
change the content-type
debadutta98 Mar 5, 2023
918272b
factorize to isChunkBlob
debadutta98 Mar 10, 2023
8da18d9
forget to change it one place
debadutta98 Mar 10, 2023
0423767
change validation checks
debadutta98 Mar 10, 2023
bf925a2
made changes as per suggested comments
debadutta98 Mar 10, 2023
18186ce
passing error through middleware
debadutta98 Mar 10, 2023
deba02a
optimize code
debadutta98 Mar 13, 2023
5b8c3dc
change testcase
debadutta98 Mar 13, 2023
aed5c38
change expected output and actual output
debadutta98 Mar 13, 2023
cf5e053
implement solution for high volume of blob data
debadutta98 Apr 24, 2023
9af4a61
Added JSdoc syntax to improve readability
debadutta98 Apr 24, 2023
c54dc54
resolve testcase issue for node v14 and v15
debadutta98 Apr 24, 2023
866e30f
check condition for module not found
debadutta98 Apr 24, 2023
4f1e2d3
handle back pressure
debadutta98 May 6, 2023
1b08824
remove unnessary lines of code and update the testcase
debadutta98 May 6, 2023
6addd8c
update the testcase
debadutta98 May 6, 2023
ca967e3
update send method
debadutta98 May 6, 2023
189f765
update
debadutta98 May 6, 2023
d237428
update
debadutta98 May 6, 2023
25e2b72
handle backpressure if blob.stream is not supported by node versions
debadutta98 May 31, 2023
6b98772
remove the wrong implementation
debadutta98 Jun 6, 2023
23b2b8d
update
debadutta98 Jun 11, 2023
bee5e0f
remove default charset from blob stream
debadutta98 Jun 14, 2023
0072acd
implement feedbacks given by @dougwilson
debadutta98 Jun 19, 2023
12164e1
maintain 100% code coverage
debadutta98 Jun 19, 2023
f79fb89
Revert "maintain 100% code coverage"
debadutta98 Jun 19, 2023
585db67
resolve issue for which testcases failed
debadutta98 Jun 20, 2023
b205372
reduce the time to 0.2
debadutta98 Jun 20, 2023
ebefbc9
update
debadutta98 Jun 20, 2023
0c2cf7e
resolve issue for node 14
debadutta98 Jun 21, 2023
d511eae
updated
debadutta98 Jun 21, 2023
a5c65e5
remove unnessary testcase and change the order of execution of line
debadutta98 Jun 30, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 19 additions & 6 deletions lib/response.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ var deprecate = require('depd')('express');
var encodeUrl = require('encodeurl');
var escapeHtml = require('escape-html');
var http = require('http');
var Blob = require('buffer').Blob;
var isAbsolute = require('./utils').isAbsolute;
var onFinished = require('on-finished');
var path = require('path');
Expand All @@ -34,12 +35,12 @@ var extname = path.extname;
var mime = send.mime;
var resolve = path.resolve;
var vary = require('vary');

/**
* Response prototype.
* @public
*/


var res = Object.create(http.ServerResponse.prototype)

/**
Expand Down Expand Up @@ -104,7 +105,7 @@ res.links = function(links){
* res.send({ some: 'json' });
* res.send('<p>some html</p>');
*
* @param {string|number|boolean|object|Buffer} body
* @param {string|number|boolean|object|Buffer|Blob} body
* @public
*/

Expand All @@ -113,10 +114,11 @@ res.send = function send(body) {
var encoding;
var req = this.req;
var type;

// settings
var app = this.app;

var isChunkBlob = !!(Blob && chunk instanceof Blob);

// allow status / body
if (arguments.length === 2) {
// res.send(body, status) backwards compat
Expand Down Expand Up @@ -158,6 +160,9 @@ res.send = function send(body) {
if (!this.get('Content-Type')) {
this.type('bin');
}
} else if (isChunkBlob) {
this.set('Content-Type', chunk.type || this.get('Content-Type') || 'application/octet-stream')
debadutta98 marked this conversation as resolved.
Show resolved Hide resolved
this.set('Content-Length', chunk.size);
} else {
return this.json(chunk);
}
Expand All @@ -181,15 +186,14 @@ res.send = function send(body) {

// populate Content-Length
var len
if (chunk !== undefined) {
if (chunk !== undefined && !isChunkBlob) {
if (Buffer.isBuffer(chunk)) {
// get length of Buffer
len = chunk.length
} else if (!generateETag && chunk.length < 1000) {
// just calculate length when no ETag + small chunk
len = Buffer.byteLength(chunk, encoding)
} else {
// convert chunk to Buffer and calculate
debadutta98 marked this conversation as resolved.
Show resolved Hide resolved
chunk = Buffer.from(chunk, encoding)
encoding = undefined;
len = chunk.length
Expand Down Expand Up @@ -229,7 +233,16 @@ res.send = function send(body) {
this.end();
} else {
// respond
this.end(chunk, encoding);
if (isChunkBlob) {
var response = this;
chunk.arrayBuffer().then(function (result) {
debadutta98 marked this conversation as resolved.
Show resolved Hide resolved
response.end(Buffer.from(result), encoding);
debadutta98 marked this conversation as resolved.
Show resolved Hide resolved
}).catch(function(err){
req.next(err);
})
} else {
this.end(chunk, encoding);
}
}

return this;
Expand Down
64 changes: 64 additions & 0 deletions test/res.send.js
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,70 @@ describe('res', function(){
})
})

describe('.send(Blob)', function(){
var buffer = require('buffer');

it('should send as blob type', function (done) {
if (buffer.Blob) {
debadutta98 marked this conversation as resolved.
Show resolved Hide resolved
var str = '<h1>express app</h1>';
var blob = new buffer.Blob([str], { type: 'text/html' });
var app = express();
app.use(function (req, res) {
res.send(blob);
});

request(app)
.get('/')
.expect('Content-Type','text/html; charset=utf-8')
debadutta98 marked this conversation as resolved.
Show resolved Hide resolved
.expect('Content-Length',blob.size.toString())
.expect(200,'<h1>express app</h1>',done)
} else {
this.skip();
}
})

it('should take default content type of application/octet-stream', function(done){
if (buffer.Blob) {
var str = '<h1>express app</h1>';
var blob = new buffer.Blob([str]);
var app = express();
app.use(function (req, res) {
res.send(blob);
});

request(app)
.get('/')
.expect('Content-Type', 'application/octet-stream')
.expect('Content-Length', blob.size.toString())
.expect(200,done)
} else {
this.skip();
}
})

it('should throw error',function (done) {
if(buffer.Blob) {
var blob = new buffer.Blob(['<h1>express app</h1>'], { type: 'text/html' });
blob.arrayBuffer = function () {
return Promise.reject('unable to read array buffer')
}
var app = express();
app.use('/', function (req, res) {
res.send(blob)
});
request(app)
.get('/')
.expect(500)
.end(function(err,res){
assert.strictEqual(/unable to read array buffer/.test(res.text), true, res.text);
done();
})
} else {
this.skip();
}
})
})

describe('when the request method is HEAD', function(){
it('should ignore the body', function(done){
var app = express();
Expand Down