http: fixed socket.setEncoding fatal error

Applied updates from previous pull-requests to disallow
socket.setEncoding before a http connection is parsed.
Wrapped `socket.setEncoding` to throw an error.
This previously resulted in a fatal error.

PR-URL: https://github.com/nodejs/node/pull/33405
Fixes: https://github.com/nodejs/node/issues/18118
Refs: https://github.com/nodejs/node/pull/18178
Refs: https://github.com/nodejs/node/pull/19344
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Ruben Bridgewater <ruben@bridgewater.de>
This commit is contained in:
iskore 2020-05-14 13:29:16 -04:00 committed by Ruben Bridgewater
parent 10596b601e
commit 32b641e528
4 changed files with 43 additions and 0 deletions

View File

@ -943,6 +943,11 @@ An invalid HTTP header value was specified.
Status code was outside the regular status code range (100-999).
<a id="ERR_HTTP_SOCKET_ENCODING"></a>
### `ERR_HTTP_SOCKET_ENCODING`
Changing the socket encoding is not allowed per [RFC 7230 Section 3][].
<a id="ERR_HTTP_TRAILER_INVALID"></a>
### `ERR_HTTP_TRAILER_INVALID`
@ -2613,6 +2618,7 @@ such as `process.stdout.on('data')`.
[exports]: esm.html#esm_package_entry_points
[file descriptors]: https://en.wikipedia.org/wiki/File_descriptor
[policy]: policy.html
[RFC 7230 Section 3]: https://tools.ietf.org/html/rfc7230#section-3
[stream-based]: stream.html
[syscall]: http://man7.org/linux/man-pages/man2/syscalls.2.html
[Subresource Integrity specification]: https://www.w3.org/TR/SRI/#the-integrity-attribute

View File

@ -63,6 +63,7 @@ const {
const {
ERR_HTTP_HEADERS_SENT,
ERR_HTTP_INVALID_STATUS_CODE,
ERR_HTTP_SOCKET_ENCODING,
ERR_INVALID_ARG_TYPE,
ERR_INVALID_CHAR
} = codes;
@ -476,6 +477,7 @@ function connectionListenerInternal(server, socket) {
socket.on = generateSocketListenerWrapper('on');
socket.addListener = generateSocketListenerWrapper('addListener');
socket.prependListener = generateSocketListenerWrapper('prependListener');
socket.setEncoding = socketSetEncoding;
// We only consume the socket if it has never been consumed before.
if (socket._handle && socket._handle.isStreamBase &&
@ -493,6 +495,10 @@ function connectionListenerInternal(server, socket) {
socket._paused = false;
}
function socketSetEncoding() {
throw new ERR_HTTP_SOCKET_ENCODING();
}
function updateOutgoingData(socket, state, delta) {
state.outgoingData += delta;
socketOnDrain(socket, state);

View File

@ -935,6 +935,8 @@ E('ERR_HTTP_HEADERS_SENT',
E('ERR_HTTP_INVALID_HEADER_VALUE',
'Invalid value "%s" for header "%s"', TypeError);
E('ERR_HTTP_INVALID_STATUS_CODE', 'Invalid status code: %s', RangeError);
E('ERR_HTTP_SOCKET_ENCODING',
'Changing the socket encoding is not allowed per RFC7230 Section 3.', Error);
E('ERR_HTTP_TRAILER_INVALID',
'Trailers are invalid with this transfer encoding', Error);
E('ERR_INCOMPATIBLE_OPTION_PAIR',

View File

@ -0,0 +1,29 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const http = require('http');
const server = http.createServer().listen(0, connectToServer);
server.on('connection', common.mustCall((socket) => {
assert.throws(
() => {
socket.setEncoding('');
},
{
code: 'ERR_HTTP_SOCKET_ENCODING',
name: 'Error',
message: 'Changing the socket encoding is not ' +
'allowed per RFC7230 Section 3.'
}
);
socket.end();
}));
function connectToServer() {
const client = new http.Agent().createConnection(this.address().port, () => {
client.end();
}).on('end', () => server.close());
}