react-native: 0.72: websockets malformed authorization headers only on iOS
Description
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 {};
}
})
);
I’ve also opened an issue on graphql-ws
repo: https://github.com/enisdenjo/graphql-ws/issues/485
React Native Version
0.72.0
Output of npx react-native info
System: OS: macOS 13.4 CPU: (20) arm64 Apple M1 Ultra Memory: 613.11 MB / 64.00 GB Shell: version: “5.9” path: /bin/zsh Binaries: Node: version: 18.16.0 path: ~/.nvm/versions/node/v18.16.0/bin/node Yarn: version: 1.22.19 path: ~/.nvm/versions/node/v18.16.0/bin/yarn npm: version: 9.7.1 path: ~/.nvm/versions/node/v18.16.0/bin/npm Watchman: version: 2023.04.10.00 path: /opt/homebrew/bin/watchman Managers: CocoaPods: version: 1.12.1 path: /opt/homebrew/opt/ruby@2.7/bin/pod SDKs: iOS SDK: Platforms: - DriverKit 22.4 - iOS 16.4 - macOS 13.3 - tvOS 16.4 - watchOS 9.4 Android SDK: Not Found IDEs: Android Studio: 2022.2 AI-222.4459.24.2221.10121639 Xcode: version: 14.3.1/14E300c path: /usr/bin/xcodebuild Languages: Java: version: 17.0.6 path: /usr/bin/javac Ruby: version: 2.7.8 path: /opt/homebrew/opt/ruby@2.7/bin/ruby npmPackages: “@react-native-community/cli”: Not Found react: installed: 18.2.0 wanted: ^18.2.0 react-native: installed: 0.72.0 wanted: 0.72.0 react-native-macos: Not Found npmGlobalPackages: “react-native”: Not Found Android: hermesEnabled: true newArchEnabled: false iOS: hermesEnabled: true newArchEnabled: false
Steps to reproduce
Nothing special, just upgraded from react-native 0.71.11
to 0.72.0
Snack, code example, screenshot, or link to a repository
no snack, it needs a minimal Hasura or other websocket API, sorry 😦
About this issue
- Original URL
- State: closed
- Created a year ago
- Comments: 18 (6 by maintainers)
In the meanwhile, for anyone that can’t wait for this to land on
main
here’s how to patch it with cocoapods-patch plugin:notice: using direct
gem 'cocoapods-patch', git: 'https://github.com/crherman7/cocoapods-patch.git', branch: 'feat/cocoapods_1.12.0'
onGemfile
breaks thepod install
so this is the only way to go I guess.on
Podfile
add this plugin right belowplatform :ios, '13.0'
on
Gemfile
add:install bundles:
install this gem from command line to download the
cocoapods-patch
that supportscocoapods@1.12.x
(PR)open Xcode or find this file and open it in an editor: (or create
SocketRocket+0.6.0.diff
underios/patches
and paste the diff you’ll find below into it and simply runpod install
afterwards)/Users/stathis/IdeaProjects/<your_app_name>/ios/Pods/SocketRocket/SocketRocket/Internal/Utilities/SRURLUtilities.m
Apply the changes from the PR on line 44:
on terminal go to
ios
folder and run:A patch will be applied and stored under
ios/patches
folder so everytime you runpod install
it will be applied.SocketRocket+0.6.0.diff
:if you’re using a
CI
tool then create a step and add this line on bash right afterbundle install
stepgem specific_install 'https://github.com/crherman7/cocoapods-patch.git' -b 'feat/cocoapods_1.12.0'
I’ll try to reach out to the team handling the library to see if we can push a release soon!
So, we can’t really use SocketRocket 0.7.0 because Flipper depends on SocketRocket
~> 0.6.0
, and we can’t bump Flipper for major compat issues with Android’s NDK. So we pushed aSocketRocket 0.6.1
with the fix and we are releasing 0.72.1 with SocketRocket 0.6.1. It should be out in some hours and you won’t need patches anymore! 😄Hi @efstathiosntonas, thanks for reporting. So we have to push SocketRocket team to merge the diff, make a release and update the dependency, probably.
It occurs under the exact same conditions however. @carlosalmonte04
My websocket connections work for Android, Web and even on iOS for
ws://
linksOnly the secure
wss://
seems to break for iOS.@cipolleschi thanks for the update, I’m not using Flipper because of Firebase so I never saw this compatibility issue.
@cipolleschi thanks, it took me a good amount of time to track this down 😅
I don’t know if that PR needs extra testing, it just fulfills my current authentication flow.