Repository: nodejs/node
Pull request: http: remove misleading warning

There are cases where the `'clientError'` event can be emitted multiple times, even if the socket is correctly destroyed.

Fixes: https://github.com/nodejs/node/issues/51073

<!--
Before submitting a pull request, please read:

- the CONTRIBUTING guide at https://github.com/nodejs/node/blob/HEAD/CONTRIBUTING.md
- the commit message formatting guidelines at
  https://github.com/nodejs/node/blob/HEAD/doc/contributing/pull-requests.md#commit-message-guidelines

For code changes:
1. Include tests for any bug fixes or new features.
2. Update documentation if relevant.
3. Ensure that `make -j4 test` (UNIX), or `vcbuild test` (Windows) passes.

If you believe this PR should be highlighted in the Node.js CHANGELOG
please add the `notable-change` label.

Developer's Certificate of Origin 1.1

By making a contribution to this project, I certify that:

(a) The contribution was created in whole or in part by me and I
    have the right to submit it under the open source license
    indicated in the file; or

(b) The contribution is based upon previous work that, to the best
    of my knowledge, is covered under an appropriate open source
    license and I have the right under that license to submit that
    work with modifications, whether created in whole or in part
    by me, under the same open source license (unless I am
    permitted to submit under a different license), as indicated
    in the file; or

(c) The contribution was provided directly to me by some other
    person who certified (a), (b) or (c) and I have not modified
    it.

(d) I understand and agree that this project and the contribution
    are public and that a record of the contribution (including all
    personal information I submit with it, including my sign-off) is
    maintained indefinitely and may be redistributed consistent with
    this project or the open source license(s) involved.
-->


Changed files:
filename: lib/_http_server.js
patch: @@ -866,27 +866,12 @@ const requestHeaderFieldsTooLargeResponse = Buffer.from(
   'Connection: close\r\n\r\n', 'ascii',
 );
 
-function warnUnclosedSocket() {
-  if (warnUnclosedSocket.emitted) {
-    return;
-  }
-
-  warnUnclosedSocket.emitted = true;
-  process.emitWarning(
-    'An error event has already been emitted on the socket. ' +
-    'Please use the destroy method on the socket while handling ' +
-    "a 'clientError' event.",
-  );
-}
-
 function socketOnError(e) {
   // Ignore further errors
   this.removeListener('error', socketOnError);
 
   if (this.listenerCount('error', noop) === 0) {
     this.on('error', noop);
-  } else {
-    warnUnclosedSocket();
   }
 
   if (!this.server.emit('clientError', e, this)) {

filename: test/parallel/test-http-server-multiple-client-error.js
patch: @@ -0,0 +1,55 @@
+'use strict';
+const common = require('../common');
+
+// Test that the `'clientError'` event can be emitted multiple times even if the
+// socket is correctly destroyed and that no warning is raised.
+
+const assert = require('assert');
+const http = require('http');
+const net = require('net');
+
+process.on('warning', common.mustNotCall());
+
+function socketListener(socket) {
+  const firstByte = socket.read(1);
+  if (firstByte === null) {
+    socket.once('readable', () => {
+      socketListener(socket);
+    });
+    return;
+  }
+
+  socket.unshift(firstByte);
+  httpServer.emit('connection', socket);
+}
+
+const netServer = net.createServer(socketListener);
+const httpServer = http.createServer(common.mustNotCall());
+
+httpServer.once('clientError', common.mustCall((err, socket) => {
+  assert.strictEqual(err.code, 'HPE_INVALID_METHOD');
+  assert.strictEqual(err.rawPacket.toString(), 'Q');
+  socket.destroy();
+
+  httpServer.once('clientError', common.mustCall((err) => {
+    assert.strictEqual(err.code, 'HPE_INVALID_METHOD');
+    assert.strictEqual(
+      err.rawPacket.toString(),
+      'WE http://example.com HTTP/1.1\r\n\r\n'
+    );
+  }));
+}));
+
+netServer.listen(0, common.mustCall(() => {
+  const socket = net.createConnection(netServer.address().port);
+
+  socket.on('connect', common.mustCall(() => {
+    socket.end('QWE http://example.com HTTP/1.1\r\n\r\n');
+  }));
+
+  socket.on('close', () => {
+    netServer.close();
+  });
+
+  socket.resume();
+}));

filename: test/parallel/test-http-socket-error-listeners.js
patch: @@ -1,5 +1,3 @@
-// Flags: --no-warnings
-
 'use strict';
 
 const common = require('../common');
@@ -17,7 +15,7 @@ const net = require('net');
 {
   let i = 0;
   let socket;
-  process.on('warning', common.mustCall());
+  process.on('warning', common.mustNotCall());
 
   const server = http.createServer(common.mustNotCall());