create-react-app: Upgrading to 3.3.0 from 3.3.0-next.62 breaks proxied ws connections

Downgrading back to react-scripts@3.2.0 fixes this. It will be fixed soon.

Describe the bug

For the past week I’ve been working with react-scripts@3.3.0-next.62 to use typescript 3.7 features. I just upgraded to 3.3.0 as it was just released. (EDIT: Upgrading to 3.3.0-next.80 causes the same issue as 3.3.0)

My application uses the package.json proxy setting to proxy both http and ws connections. This has been working fine, but upgrading to 3.3.0 causes the socket connections to break. Downgrading to 3.3.0-next.62 causes it to start working again.

Did you try recovering your dependencies?

Yes - I deleted node_modules and package-lock.json and reinstalled. The same result was encountered. I am also on the latest npm version (which still works with 3.3.0-next.62

Which terms did you search for in User Guide?

I searched for websocket proxy issues - the closest I found was issue 6497 but this does not seem to be the same.

Environment

System:
    OS: Windows 10 10.0.18362
    CPU: (8) x64 Intel(R) Core(TM) i7-6700HQ CPU @ 2.60GHz
  Binaries:
    Node: 13.3.0 - C:\Program Files\nodejs\node.EXE
    Yarn: Not Found
    npm: 6.13.2 - C:\Program Files\nodejs\npm.CMD
  Browsers:
    Edge: 44.18362.449.0
    Internet Explorer: 11.0.18362.1
  npmPackages:
    react: ^16.12.0 => 16.12.0
    react-dom: ^16.12.0 => 16.12.0
    react-scripts: ^3.3.0 => 3.3.0
  npmGlobalPackages:
    create-react-app: Not Found

^ as a note to the above, I was on node 12 when I first encountered this error, but checked if an upgrade would resolve the problem.

Steps to reproduce

  1. Upgrade react-scripts with npm install --save-dev react-scripts@3.3.0
  2. Add a proxy value in package.json to match a local service that serves http and ws (eg. "proxy": "http://localhost:8080/")
  3. Ensure your web app makes some connection to the proxied websocket
  4. Run the app with npm start and view the app

Expected behavior

The proxied websocket connection should behave normally.

Actual behavior

Console logs output the following:

The connection to ws://localhost:3000/subscriptions was interrupted while the page was loading.
Firefox can’t establish a connection to the server at ws://localhost:3000/subscriptions.

in Chrome, a similar log is output:

WebSocket connection to 'ws://localhost:3000/subscriptions' failed: Error during WebSocket handshake: Unexpected response code: 400

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 35
  • Comments: 27 (6 by maintainers)

Commits related to this issue

Most upvoted comments

Guys, this just broke our app… Don’t push broken code, please and thank you.

@dankolesnikov You have never pushed broken code right? If you are that great, good for you, but others are just humans that do mistakes.

You can be also more proactive with your brilliant mind and fix the problem instead of waiting for others to do it, you know?

Releasing in the next couple hours.

Same problem here, it works fine with 3.2.0 and breaks with 3.3.0 with an WebSocket connection to 'ws://localhost:3000/socket.io/?EIO=3&transport=websocket&sid=ZuPVIkaei-I3cSozAAAH' failed: Error during WebSocket handshake: Unexpected response code: 400 error.

I’m using Socket.io, but it seems this breaks on all websocket implementations.

This is already fixed in master. Shouldn’t a release of a new version be enough to fix this bug?

@Lowgain can you put Downgrading back to react-scripts@3.2.0 fixes this. It will be fixed soon. at the top of the issue for anybody new coming in here?

Guys, can you please release a version?

@Lowgain can you put Downgrading back to react-scripts@3.2.0 fixes this. It will be fixed soon. at the top of the issue for anybody new coming in here?

Sure - all done!

Related to webpack/webpack-dev-server#2310 Manually upgrading to webpack-dev-server 3.10.1 fixed it for me.

We run api server on port 4000 and cra on 3000. We have setupProxy.js:

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

const target = process.env.REACT_APP_API_URL || 'http://localhost:4000/';

module.exports = function(app) {
  app.use(
    proxy('/api', {
      ws: true,
      changeOrigin: true,
      target,
    }),
  );
};

But because of this issue we cannot connect websockets to /api/ws but instead we can connect to ws://localhost:4000/api/ws directly from browser. You lose the benefit of proxy but don’t have to downgrade.

const getCorrectProtocol = () =>
  window.location.protocol === 'http:' ? 'ws' : 'wss';

const getWsUri = (path: string) => {
  // Because of https://github.com/facebook/create-react-app/issues/8094 in development we have to connect to API directly
  // websockets don't adhere to same-site policy so no cors necessary
  if (process.env.NODE_ENV === 'development') {
    const apiUrl = process.env.REACT_APP_API_URL?.replace(
      'https',
      'wss',
    )?.replace('http', 'ws');
    return `${apiUrl}${path}`;
  }
  // safari incorrectly implement CSP self keyword for websockets
  // https://github.com/w3c/webappsec-csp/issues/7
  return `${getCorrectProtocol()}://${window.location.host}${path}`;
};

const wsLink = new WebSocketLink({
  uri: getWsUri(GRAPHQL_URI),
  // ...
});

The key is REACT_APP_API_URL env variable that tells browser where our api server is.

Oh my God… I spent over 12H straight surfing the internet , wondering what could be the issue… Am just gonna downgrade for now… already wasted too much time on this…

When can we expect a release that fixes this issue?

I don’t think suggesting ejecting is a very good idea in this case. Just wait for the minor release.

I also downgraded to 3.2.0, but my builds are now red because of the security vulnerability @3.2.0


                       === npm audit security report ===

# Run  npm install react-scripts@3.3.0  to resolve 1 vulnerability
┌───────────────┬──────────────────────────────────────────────────────────────┐
│ Moderate      │ Cross-Site Scripting                                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Package       │ serialize-javascript                                         │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Dependency of │ react-scripts                                                │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ Path          │ react-scripts > terser-webpack-plugin > serialize-javascript │
├───────────────┼──────────────────────────────────────────────────────────────┤
│ More info     │ https://npmjs.com/advisories/1426                            │
└───────────────┴──────────────────────────────────────────────────────────────┘

Got the same issue

SecurityError: Failed to construct 'WebSocket': An insecure WebSocket connection may not be initiated from a page loaded over HTTPS
webpackHotDevClient.js:60 Mixed Content: The page at 'https://local.smth.com:3000/' was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint 'ws://local.smth.com:3000/sockjs-node'. This request has been blocked; this endpoint must be available over WSS.
Uncaught DOMException: Failed to construct 'WebSocket': An insecure WebSocket connection may not be initiated from a page loaded over HTTPS.
    at Object../node_modules/react-dev-utils/webpackHotDevClient.js

Can reproduce on Chrome without proxy. Tried to visit dev server and got an error like this.