node-http-proxy icon indicating copy to clipboard operation
node-http-proxy copied to clipboard

ERR_STREAM_WRITE_AFTER_END write after end

Open guillaume-at-palo opened this issue 5 years ago • 7 comments

I often get the following error when I run tests through cypress. I suppose that connections from the browser are reseted and so the socket is closed.

error: write after end {"name":"Error [ERR_STREAM_WRITE_AFTER_END]","stack":"Error [ERR_STREAM_WRITE_AFTER_END]: write after end
    at writeAfterEnd (_stream_writable.js:243:12)
    at Socket.Writable.write (_stream_writable.js:291:5)
    at ClientRequest.<anonymous> (/app/node_modules/http-proxy/lib/http-proxy/passes/ws-incoming.js:115:16)
    at ClientRequest.emit (events.js:182:13)
    at ClientRequest.EventEmitter.emit (domain.js:442:20)
    at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:555:21)
    at HTTPParser.parserOnHeadersComplete (_http_common.js:109:17)
    at Socket.socketOnData (_http_client.js:441:20)
    at Socket.emit (events.js:182:13)
    at Socket.EventEmitter.emit (domain.js:442:20)","code":"ERR_STREAM_WRITE_AFTER_END"}

Testing if socket is open in ws-incoming.js seems to solve the issue

    proxyReq.on('response', function (res) {
      // if upgrade event isn't going to happen, close the socket
      if (!res.upgrade && socket.readyState === socket.OPEN) {
        socket.write(createHttpHeader('HTTP/' + res.httpVersion + ' ' + res.statusCode + ' ' + res.statusMessage, res.headers));
        res.pipe(socket);
      }
    });

Is it the right way to solve the issue ?

guillaume-at-palo avatar May 23 '19 09:05 guillaume-at-palo

Got the same issue with Firefox, signalr, CRA and proxy-middleware.

`-- [email protected]
  `-- [email protected]

I've configured my proxy like this:

const proxy = require("http-proxy-middleware");

module.exports = function(app) {
    app.use(proxy("/cms",
        {
            target: "http://localhost:91",
            changeOrigin: true, // needed for virtual hosted sites
            ws: true, // proxy websockets
            pathRewrite: {
                "^/cms": "/"
            }
        }));
};

Every time when signalr sends a request the started app crashes with this error:

events.js:167
      throw er; // Unhandled 'error' event
      ^

Error [ERR_STREAM_WRITE_AFTER_END]: write after end
    at writeAfterEnd (_stream_writable.js:243:12)
    at Socket.Writable.write (_stream_writable.js:291:5)
    at ClientRequest.<anonymous> (c:\Projects\Pp2\source\Pp\Front\Pp3.Web\ClientApp\node_modules\http-proxy\lib\http-proxy\passes\ws-incoming.js:115:16)
    at ClientRequest.emit (events.js:182:13)
    at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:555:21)
    at HTTPParser.parserOnHeadersComplete (_http_common.js:109:17)
    at Socket.socketOnData (_http_client.js:441:20)
    at Socket.emit (events.js:182:13)
    at addChunk (_stream_readable.js:283:12)
    at readableAddChunk (_stream_readable.js:264:11)
    at Socket.Readable.push (_stream_readable.js:219:10)
    at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)
Emitted 'error' event at:
    at writeAfterEnd (_stream_writable.js:245:10)
    at Socket.Writable.write (_stream_writable.js:291:5)
    [... lines matching original stack trace ...]
    at TCP.onStreamRead [as onread] (internal/stream_base_commons.js:94:17)

xumix avatar Aug 14 '19 11:08 xumix

Any news? This is really annoying, my development server crashes every several minutes because of this bug.

xumix avatar Sep 04 '19 17:09 xumix

Testing if socket is open in ws-incoming.js seems to solve the issue

    proxyReq.on('response', function (res) {
      // if upgrade event isn't going to happen, close the socket
      if (!res.upgrade && socket.readyState === socket.OPEN) {
        socket.write(createHttpHeader('HTTP/' + res.httpVersion + ' ' + res.statusCode + ' ' + res.statusMessage, res.headers));
        res.pipe(socket);
      }
    });

Is it the right way to solve the issue ?

this way solved my problem, and has been running normally in prodution for several months

caosm avatar Jan 02 '20 02:01 caosm

Is @caosm's solution the correct one and if yes, could that be merged?

Is there a way of achieving that same workaround without patching the library?

I am having the same issue as @xumix

dpwrussell avatar Aug 25 '20 13:08 dpwrussell

The fix from @caosm also resolved my issue, is there no pull request to fix this?

dcbarans avatar Mar 31 '21 17:03 dcbarans

Just hit this one today… the fact that the client can basically terminate the TCP connection at any time leaves the server vulnerable to a denial-of-service triggerable by any HTTP client that establishes a websocket connection first. (Or to any spoofed TCP RST packet.)

sjlongland avatar Aug 16 '22 02:08 sjlongland

@jcrugzz is there plan for a maintenance release in the near future for this issue? Please see here for PR.

SamuelToh avatar Aug 25 '22 02:08 SamuelToh