Skip to content

Commit 4732f15

Browse files
committed
http: don't throw on Uint8Arrays for http.ServerResponse#write
Don't throw errors on Uint8Arrays and added test for all valid types. Backport-PR-URL: nodejs#33490 PR-URL: nodejs#33155 Fixes: nodejs#33379 Refs: nodejs#29829 Reviewed-By: Robert Nagy <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Zeyu Yang <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 5de5734 commit 4732f15

File tree

3 files changed

+51
-7
lines changed

3 files changed

+51
-7
lines changed

lib/_http_outgoing.js

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,11 +56,13 @@ const {
5656
ERR_METHOD_NOT_IMPLEMENTED,
5757
ERR_STREAM_CANNOT_PIPE,
5858
ERR_STREAM_ALREADY_FINISHED,
59+
ERR_STREAM_NULL_VALUES,
5960
ERR_STREAM_WRITE_AFTER_END
6061
},
6162
hideStackFrames
6263
} = require('internal/errors');
6364
const { validateString } = require('internal/validators');
65+
const { isUint8Array } = require('internal/util/types');
6466

6567
const HIGH_WATER_MARK = getDefaultHighWaterMark();
6668
const { CRLF, debug } = common;
@@ -651,6 +653,16 @@ function writeAfterEnd(msg, callback) {
651653
}
652654

653655
function write_(msg, chunk, encoding, callback, fromEnd) {
656+
if (typeof callback !== 'function')
657+
callback = function() {};
658+
659+
if (chunk === null)
660+
throw new ERR_STREAM_NULL_VALUES();
661+
662+
if (typeof chunk !== 'string' && !isUint8Array(chunk))
663+
throw new ERR_INVALID_ARG_TYPE(
664+
'chunk', ['string', 'Buffer', 'Uint8Array'], chunk);
665+
654666
if (msg.finished) {
655667
writeAfterEnd(msg, callback);
656668
return true;
@@ -667,9 +679,9 @@ function write_(msg, chunk, encoding, callback, fromEnd) {
667679
return true;
668680
}
669681

670-
if (!fromEnd && typeof chunk !== 'string' && !(chunk instanceof Buffer)) {
682+
if (!fromEnd && typeof chunk !== 'string' && !(isUint8Array(chunk))) {
671683
throw new ERR_INVALID_ARG_TYPE('first argument',
672-
['string', 'Buffer'], chunk);
684+
['string', 'Buffer', 'Uint8Array'], chunk);
673685
}
674686

675687
if (!fromEnd && msg.socket && !msg.socket.writableCorked) {

test/parallel/test-http-outgoing-proto.js

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,16 +74,24 @@ assert.throws(() => {
7474
);
7575
}
7676

77-
assert(OutgoingMessage.prototype.write.call({ _header: 'test' }));
77+
assert.throws(() => {
78+
const outgoingMessage = new OutgoingMessage();
79+
outgoingMessage.write.call({ _header: 'test' });
80+
}, {
81+
code: 'ERR_INVALID_ARG_TYPE',
82+
name: 'TypeError',
83+
message: 'The "chunk" argument must be of type string or an instance of ' +
84+
'Buffer or Uint8Array. Received undefined'
85+
});
7886

7987
assert.throws(() => {
8088
const outgoingMessage = new OutgoingMessage();
8189
outgoingMessage.write.call({ _header: 'test', _hasBody: 'test' });
8290
}, {
8391
code: 'ERR_INVALID_ARG_TYPE',
8492
name: 'TypeError',
85-
message: 'The first argument must be of type string or an instance of ' +
86-
'Buffer. Received undefined'
93+
message: 'The "chunk" argument must be of type string or an instance of ' +
94+
'Buffer or Uint8Array. Received undefined'
8795
});
8896

8997
assert.throws(() => {
@@ -92,8 +100,8 @@ assert.throws(() => {
92100
}, {
93101
code: 'ERR_INVALID_ARG_TYPE',
94102
name: 'TypeError',
95-
message: 'The first argument must be of type string or an instance of ' +
96-
'Buffer. Received type number (1)'
103+
message: 'The "chunk" argument must be of type string or an instance of ' +
104+
'Buffer or Uint8Array. Received type number (1)'
97105
});
98106

99107
// addTrailers()
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
'use strict';
2+
const common = require('../common');
3+
const assert = require('assert');
4+
const http = require('http');
5+
6+
const httpServer = http.createServer(common.mustCall(function(req, res) {
7+
httpServer.close();
8+
assert.throws(() => {
9+
res.write(['Throws.']);
10+
}, {
11+
code: 'ERR_INVALID_ARG_TYPE'
12+
});
13+
// should not throw
14+
res.write('1a2b3c');
15+
// should not throw
16+
res.write(new Uint8Array(1024));
17+
// should not throw
18+
res.write(Buffer.from('1'.repeat(1024)));
19+
res.end();
20+
}));
21+
22+
httpServer.listen(0, common.mustCall(function() {
23+
http.get({ port: this.address().port });
24+
}));

0 commit comments

Comments
 (0)