Skip to content

Commit 24eaeed

Browse files
apapirovskitargos
authored andcommitted
http: fix socketOnWrap edge cases
Properly handle prependListener wrapping on http server socket, in addition to on and addListener. PR-URL: #27968 Reviewed-By: Yongsheng Zhang <[email protected]> Reviewed-By: Luigi Pinca <[email protected]> Reviewed-By: Rich Trott <[email protected]>
1 parent 70b4854 commit 24eaeed

File tree

2 files changed

+37
-35
lines changed

2 files changed

+37
-35
lines changed

lib/_http_server.js

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -407,9 +407,10 @@ function connectionListenerInternal(server, socket) {
407407
socket.on('resume', onSocketResume);
408408
socket.on('pause', onSocketPause);
409409

410-
// Override on to unconsume on `data`, `readable` listeners
411-
socket.on = socketOnWrap;
412-
socket.addListener = socket.on;
410+
// Overrides to unconsume on `data`, `readable` listeners
411+
socket.on = generateSocketListenerWrapper('on');
412+
socket.addListener = generateSocketListenerWrapper('addListener');
413+
socket.prependListener = generateSocketListenerWrapper('prependListener');
413414

414415
// We only consume the socket if it has never been consumed before.
415416
if (socket._handle && socket._handle.isStreamBase &&
@@ -757,19 +758,21 @@ function unconsume(parser, socket) {
757758
}
758759
}
759760

760-
function socketOnWrap(ev, fn) {
761-
const res = net.Socket.prototype.on.call(this, ev, fn);
762-
if (!this.parser) {
763-
this.prependListener = net.Socket.prototype.prependListener;
764-
this.on = net.Socket.prototype.on;
765-
this.addListener = this.on;
766-
return res;
767-
}
761+
function generateSocketListenerWrapper(originalFnName) {
762+
return function socketListenerWrap(ev, fn) {
763+
const res = net.Socket.prototype[originalFnName].call(this, ev, fn);
764+
if (!this.parser) {
765+
this.on = net.Socket.prototype.on;
766+
this.addListener = net.Socket.prototype.addListener;
767+
this.prependListener = net.Socket.prototype.prependListener;
768+
return res;
769+
}
768770

769-
if (ev === 'data' || ev === 'readable')
770-
unconsume(this.parser, this);
771+
if (ev === 'data' || ev === 'readable')
772+
unconsume(this.parser, this);
771773

772-
return res;
774+
return res;
775+
};
773776
}
774777

775778
function resetHeadersTimeoutOnReqEnd() {
Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,33 @@
11
'use strict';
2-
require('../common');
2+
const common = require('../common');
33
const assert = require('assert');
44
const http = require('http');
55
const net = require('net');
66

7-
let received = '';
7+
['on', 'addListener', 'prependListener'].forEach((testFn) => {
8+
let received = '';
89

9-
const server = http.createServer(function(req, res) {
10-
res.writeHead(200);
11-
res.end();
10+
const server = http.createServer(function(req, res) {
11+
res.writeHead(200);
12+
res.end();
1213

13-
req.socket.on('data', function(data) {
14-
received += data;
15-
});
14+
req.socket[testFn]('data', function(data) {
15+
received += data;
16+
});
1617

17-
assert.strictEqual(req.socket.on, req.socket.addListener);
18-
assert.strictEqual(req.socket.prependListener,
19-
net.Socket.prototype.prependListener);
18+
server.close();
19+
}).listen(0, function() {
20+
const socket = net.connect(this.address().port, function() {
21+
socket.write('PUT / HTTP/1.1\r\n\r\n');
2022

21-
server.close();
22-
}).listen(0, function() {
23-
const socket = net.connect(this.address().port, function() {
24-
socket.write('PUT / HTTP/1.1\r\n\r\n');
23+
socket.once('data', function() {
24+
socket.end('hello world');
25+
});
2526

26-
socket.once('data', function() {
27-
socket.end('hello world');
27+
socket.on('end', common.mustCall(() => {
28+
assert.strictEqual(received, 'hello world',
29+
`failed for socket.${testFn}`);
30+
}));
2831
});
2932
});
3033
});
31-
32-
process.on('exit', function() {
33-
assert.strictEqual(received, 'hello world');
34-
});

0 commit comments

Comments
 (0)