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

EventSource upstream connection not closed

Open carlhopf opened this issue 3 years ago • 5 comments

I'm using webpack-dev-server (which uses node-http-proxy) to proxy EventSource connections. Demo project: https://github.com/carlhopf/webpack-dev-server-proxy-eventsource

When calling eventSource.close() client/browser side, the node-http-proxy upstream connection is not closed.

I fixed this attaching a listener in the proxyRes event:

res.on('close', () => {
  if (!res.finished) proxyRes.destroy();
});

I guess this could added to https://github.com/http-party/node-http-proxy/blob/1.18.1/lib/http-proxy/passes/web-incoming.js#L181

Is this the way to go, should I send a pull request?

carlhopf avatar May 06 '21 15:05 carlhopf

Is it fixed?

justice47 avatar Feb 08 '22 15:02 justice47

@carlhopf had been searching for hours and your solution fixed everything, yes they should add this to the package for sure!

victorekpo avatar Aug 24 '22 23:08 victorekpo

The workaround provided will only work the first time as the proxy is going to be destroyed

esfomeado avatar Mar 28 '23 13:03 esfomeado

I am having a similar issue with EventSource connections through http-proxy v1.18.1. Mine work in development (create-react-app), but when deploying to production, the connection fails with the following browser (chromium) error:

EventSource's response has a MIME type ("text/html") that is not "text/event-stream". Aborting the connection.

The portion of my server.js that creates the proxy is:

const httpProxy = require('http-proxy');

var app = express();
var apiProxy = httpProxy.createProxyServer({secure: false});

app.use(express.static(root));
app.use(compression());

/* proxy api calls over to port 9047 */
app.all('/api/*', (req, res) => {
   apiProxy.web(req,res, { target: 'https://localhost:9047' });
});

and the HTML document that React/NodeJS appears to be returning to the browser instead of the EventStream data is:

<!doctype html>
<html lang="en">
    <head>
        <meta charset="utf-8"/>
        <link rel="icon" href="/icons/favicon.ico"/>
        <meta name="viewport" content="width=device-width,initial-scale=1"/>
        <meta name="theme-color" content="#000000"/>
        <meta name="description" content="Web site created using create-react-app"/>
        <link rel="apple-touch-icon" href="/icons/threaded_icon_57x57.png"/>
        <link rel="manifest" href="/manifest.json"/>
        <title>My App</title>
        <script defer="defer" src="/static/js/main.8ebfafc7.js"></script>
        <link href="/static/css/main.8c23b3de.css" rel="stylesheet">
    </head>
    <body>
        <noscript>You need to enable JavaScript to run this app.</noscript>
        <div id="root"></div>
    </body>
</html>

I am 100% sure that my backend (springboot in this case) server is returning the correct response type because it works in dev, and it works in production using a non-React/express client. Any suggestions?

jnorvell avatar Aug 28 '23 17:08 jnorvell

Thanks to @didavid61202, a possible fix is merged to unjs/httpxy

pi0 avatar Sep 01 '23 18:09 pi0