diff --git a/doc/api/errors.md b/doc/api/errors.md
index 6353228f444c37..2e03bfca7374ee 100644
--- a/doc/api/errors.md
+++ b/doc/api/errors.md
@@ -934,6 +934,11 @@ An invalid HTTP header value was specified.
Status code was outside the regular status code range (100-999).
+
+### `ERR_HTTP_SOCKET_ENCODING`
+
+Changing the socket encoding is not allowed per [RFC 7230 Section 3][].
+
### `ERR_HTTP_TRAILER_INVALID`
@@ -2590,6 +2595,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
diff --git a/lib/_http_server.js b/lib/_http_server.js
index 2c7c5284f604a0..f11c74ff7c4303 100644
--- a/lib/_http_server.js
+++ b/lib/_http_server.js
@@ -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);
diff --git a/lib/internal/errors.js b/lib/internal/errors.js
index 1f5b07fe154171..5d2e116e14dca2 100644
--- a/lib/internal/errors.js
+++ b/lib/internal/errors.js
@@ -916,6 +916,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',
diff --git a/test/parallel/test-http-socket-encoding-error.js b/test/parallel/test-http-socket-encoding-error.js
new file mode 100644
index 00000000000000..0ce984896d3aea
--- /dev/null
+++ b/test/parallel/test-http-socket-encoding-error.js
@@ -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());
+}