enisdenjo / graphql-ws

Coherent, zero-dependency, lazy, simple, GraphQL over WebSocket Protocol compliant server and client.
https://the-guild.dev/graphql/ws
MIT License
1.75k stars 162 forks source link

Malformed authorization headers on react-native@0.72.0 only on iOS #485

Closed efstathiosntonas closed 1 year ago

efstathiosntonas commented 1 year ago

After upgrading from react-native@0.71.11 to 0.72.0 I get this error response from Hasura 2.27.0 on iOS, on Android it works fine.

socket closed : code 4400, reason : {"server_error_msg":"4400: Connection initialization failed: Malformed Authorization header"}

I'm not quite sure if the issue relies on graphql-ws or if something has changed on react-native that affects graphql-ws somehow. This is happening on both ws:localhost and wss:// on Testflight builds.

this is the GraphQLWsLink on "@apollo/client": "3.7.16" with "graphql-ws": "^5.13.1"

 const wsLink = new GraphQLWsLink(
      createClient({
        url: webSocketUri,
        lazy: true,
        shouldRetry: () => true,
        retryAttempts: Infinity,
        retryWait: (_count) => new Promise((r) => setTimeout(() => r(), 1000)),
        on: {
          ping: (received) => {
            if (!received /* sent */) {
              timedOut = setTimeout(() => {
                /* a close event `4499: Terminated` is issued to the current WebSocket and an
                 artificial `{ code: 4499, reason: 'Terminated', wasClean: false }` close-event-like
                 object is immediately emitted without waiting for the one coming from `WebSocket.onclose`
                 calling terminate is not considered fatal and a connection retry will occur as expected
                 see: https://github.com/enisdenjo/graphql-ws/discussions/290
                 */
                wsLink.client.terminate();
              }, 5000);
            }
          },
          pong: (received) => {
            if (received) {
              clearTimeout(timedOut);
            }
          },
          closed: (error: any) => {
            console.log("socket closed : code %s, reason : %s", error.code, error.reason);
            if (error.code !== 1000) {
              disconnectedVar(true);
            }
          },
          connected: () => {
            if (disconnectedVar()) {
              disconnectedVar(false);
            }
          },
          error: (err: any) => {
            console.log(`error in sockets, code: ${err.code}, reason: ${err.reason}`);
          }
        },
        connectionParams: async () => {
          const accessToken = await getAccessTokenRefresh();
          if (accessToken?.token) {
            return {
              headers: {
                Authorization: `Bearer ${accessToken.token}`
              }
            };
          }
          return {};
        }
      })
    );
efstathiosntonas commented 1 year ago

Maybe because of this PR?

efstathiosntonas commented 1 year ago

Seems to be a SocketRocket issue, after applying this change from this PR the issue was solved.

efstathiosntonas commented 1 year ago

Just in case someone lands here, these are the instructions to patch SocketRocket pod: https://github.com/facebook/react-native/issues/38012#issuecomment-1602288722

XChikuX commented 1 year ago

I still get this error on iOS. Using react-native 0.72.3 Any suggestions? image