Skip to content

Commit d64e773

Browse files
ronagtargos
authored andcommitted
http: make OutgoingMessage more streamlike
Implement missing getters error & closed. Add support for proper "writable" check through `isWritable` helper. We cannot fix the `OutgoingMessage.writable` property as that would break the ecosystem. PR-URL: #45672 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Gerhard Stöbich <deb2001-github@yahoo.de> Reviewed-By: Minwoo Jung <nodecorelab@gmail.com> Reviewed-By: Antoine du Hamel <duhamelantoine1995@gmail.com>
1 parent 99410ef commit d64e773

File tree

3 files changed

+78
-21
lines changed

3 files changed

+78
-21
lines changed

lib/_http_outgoing.js

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ const kCorked = Symbol('corked');
8888
const kUniqueHeaders = Symbol('kUniqueHeaders');
8989
const kBytesWritten = Symbol('kBytesWritten');
9090
const kEndCalled = Symbol('kEndCalled');
91+
const kErrored = Symbol('errored');
9192

9293
const nop = () => {};
9394

@@ -147,10 +148,26 @@ function OutgoingMessage() {
147148
this._keepAliveTimeout = 0;
148149

149150
this._onPendingData = nop;
151+
152+
this[kErrored] = null;
150153
}
151154
ObjectSetPrototypeOf(OutgoingMessage.prototype, Stream.prototype);
152155
ObjectSetPrototypeOf(OutgoingMessage, Stream);
153156

157+
ObjectDefineProperty(OutgoingMessage.prototype, 'errored', {
158+
__proto__: null,
159+
get() {
160+
return this[kErrored];
161+
},
162+
});
163+
164+
ObjectDefineProperty(OutgoingMessage.prototype, 'closed', {
165+
__proto__: null,
166+
get() {
167+
return this._closed;
168+
},
169+
});
170+
154171
ObjectDefineProperty(OutgoingMessage.prototype, 'writableFinished', {
155172
__proto__: null,
156173
get() {
@@ -320,6 +337,8 @@ OutgoingMessage.prototype.destroy = function destroy(error) {
320337
}
321338
this.destroyed = true;
322339

340+
this[kErrored] = error;
341+
323342
if (this.socket) {
324343
this.socket.destroy(error);
325344
} else {

test/parallel/test-http-client-incomingmessage-destroy.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,13 @@ server.listen(0, () => {
2020
get({
2121
port: server.address().port
2222
}, common.mustCall((res) => {
23-
res.destroy(new Error('Destroy test'));
23+
const err = new Error('Destroy test');
24+
assert.strictEqual(res.errored, null);
25+
res.destroy(err);
26+
assert.strictEqual(res.closed, false);
27+
assert.strictEqual(res.errored, err);
28+
res.on('close', () => {
29+
assert.strictEqual(res.closed, true);
30+
});
2431
}));
2532
});
Lines changed: 51 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,55 @@
11
'use strict';
22
const common = require('../common');
33
const http = require('http');
4+
const assert = require('assert');
45

5-
const server = http.createServer(common.mustCall((req, res) => {
6-
req.pipe(res);
7-
res.on('error', common.mustNotCall());
8-
res.on('close', common.mustCall(() => {
9-
res.end('asd');
10-
process.nextTick(() => {
11-
server.close();
12-
});
13-
}));
14-
})).listen(0, () => {
15-
http
16-
.request({
17-
port: server.address().port,
18-
method: 'PUT'
19-
})
20-
.on('response', (res) => {
21-
res.destroy();
22-
})
23-
.write('asd');
24-
});
6+
{
7+
const server = http.createServer(common.mustCall((req, res) => {
8+
assert.strictEqual(res.closed, false);
9+
req.pipe(res);
10+
res.on('error', common.mustNotCall());
11+
res.on('close', common.mustCall(() => {
12+
assert.strictEqual(res.closed, true);
13+
res.end('asd');
14+
process.nextTick(() => {
15+
server.close();
16+
});
17+
}));
18+
})).listen(0, () => {
19+
http
20+
.request({
21+
port: server.address().port,
22+
method: 'PUT'
23+
})
24+
.on('response', (res) => {
25+
res.destroy();
26+
})
27+
.write('asd');
28+
});
29+
}
30+
31+
{
32+
const server = http.createServer(common.mustCall((req, res) => {
33+
assert.strictEqual(res.closed, false);
34+
req.pipe(res);
35+
res.on('error', common.mustNotCall());
36+
res.on('close', common.mustCall(() => {
37+
assert.strictEqual(res.closed, true);
38+
process.nextTick(() => {
39+
server.close();
40+
});
41+
}));
42+
const err = new Error('Destroy test');
43+
res.destroy(err);
44+
assert.strictEqual(res.errored, err);
45+
})).listen(0, () => {
46+
http
47+
.request({
48+
port: server.address().port,
49+
method: 'PUT'
50+
})
51+
.on('error', common.mustCall())
52+
.write('asd');
53+
});
54+
55+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy