Skip to content

[cupertino_http] CupertinoClient requests hang and fail to complete #1702

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
martyfuhry opened this issue Jan 22, 2025 · 27 comments
Closed

[cupertino_http] CupertinoClient requests hang and fail to complete #1702

martyfuhry opened this issue Jan 22, 2025 · 27 comments
Assignees
Labels
package:cupertino_http Issues related to package:cupertino_http type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)

Comments

@martyfuhry
Copy link

martyfuhry commented Jan 22, 2025

I've been using IOClient in my Flutter application. When I switched to using CupertinoClient, my requests fail to complete. I have inspected the network traffic from my iOS app through a proxy. The requests are being properly sent by the application and the web server is responding with the correct data. But the future from client.get is never resolved in the Flutter application. No errors show up, the request simply hangs.

Here is my code for initializing the CupertinoClient

Client getHttpClient() {
  if (UniversalPlatform.isAndroid) {
    return CronetClient.defaultCronetEngine();
  } else if (UniversalPlatform.isIOS) {
    return CupertinoClient.defaultSessionConfiguration();
  } else {
    throw UnsupportedError('Platform not supported');
  }
}

Here is an example of our code sending a request:

    return client
        .get(
          url,
          headers: headers,
        );

I've also tried using UrlSessionConfiguration.ephemeralSessionConfiguration() and it does not change the result. If I change the above code to return IOClient instead of the CupertinoClient, the application works.

Finally, it would seem that every network request hangs, not just those to my own webserver. In particular, this get request hangs:

return client.get(Uri.parse('https://google.com'));

I do not see any errors in my console. The responses simply fail to resolve the future and the code hangs forever.

This was all tested on a physical iOS 17.6.1 device (iPhone 11 Pro Max).

@martyfuhry martyfuhry added package:cupertino_http Issues related to package:cupertino_http type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) labels Jan 22, 2025
@martyfuhry martyfuhry changed the title Requests hang and fail to complete [cupertino_http] CupertinoClient requests hang and fail to complete Jan 22, 2025
@brianquinlan
Copy link
Collaborator

@martyfuhry What version of cupertino_http are you using. This issue may have been resolved in the 2.0.2. release.

@martyfuhry
Copy link
Author

Ah, that would be great! I am only running 2.0.1 so I will try updating and seeing if that resolves the issue. Thank you!

@brianquinlan brianquinlan added the needs-info Additional information needed from the issue author label Jan 22, 2025
@brianquinlan
Copy link
Collaborator

OK, let me know how it goes.

@github-actions github-actions bot removed the needs-info Additional information needed from the issue author label Jan 23, 2025
@martyfuhry
Copy link
Author

Unfortunately, the behavior persists in version 2.0.2.

@brianquinlan
Copy link
Collaborator

@liamappelbe

@martyfuhry Did you ever use cuperinto_http before 2.0? If not, could you try testing your app with cupertino_http 1.5.1? If you are only using the Client interface then it should be enough to just change your pubspec.yaml

@chenfisher
Copy link

@brianquinlan downgrading to 1.5.1 solves the issue.

@martyfuhry
Copy link
Author

It does indeed work with 1.5.1. Thank you for the help.

@brianquinlan
Copy link
Collaborator

It does indeed work with 1.5.1. Thank you for the help.

That's not good. I don't have an explanation for this regression in 2.0.2.

@liamappelbe
Copy link

liamappelbe commented Jan 27, 2025

Do we know what sort of callback this code path is using? The only thing I know of that could deadlock is a blocking callback.

jnigen has a similar issue. If there's a reliable repro here I can investigate it and see if it'll be fixed by the fix we're working on for that. In the meantime it might be a good idea to remove blocking callbacks from cupertino_http.

EDIT: Actually I guess this isn't deadlocking, but just not receiving a listener callback.

@brianquinlan
Copy link
Collaborator

@liamappelbe

The listener is installed here:

ncb.NSURLSessionDataDelegate.URLSession_task_didCompleteWithError_

Presumably the request is waiting here:

result = await taskTracker.responseCompleter.future;

I don't see a path through here that doesn't complete the future:

@brianquinlan
Copy link
Collaborator

@chenfisher @martyfuhry (and possibly others):

Could you tell me a bit more about the environments where you can reproduce this issue? I take it that you can only produce the issue on a physical device? Do you see this issue with flutter run or only after building the application (e.g. with flutter build ipa)? Are you setting any flags?

@brianquinlan
Copy link
Collaborator

I tried running the demo application on a real device using both --release and --debug on a real iPhone 16 running iOS 18.1.1 and it worked fine.

$ flutter doctor -v
[!] Flutter (Channel stable, 3.27.3, on macOS 15.2 24C101 darwin-arm64, locale en)
    • Flutter version 3.27.3 on channel stable at /Users/bquinlan/flutter
    ! Warning: `dart` on your path resolves to /opt/homebrew/Cellar/dart/3.6.0/libexec/bin/dart, which is not inside your current Flutter SDK checkout at
      /Users/bquinlan/flutter. Consider adding /Users/bquinlan/flutter/bin to the front of your path.
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision c519ee916e (8 days ago), 2025-01-21 10:32:23 -0800
    • Engine revision e672b006cb
    • Dart version 3.6.1
    • DevTools version 2.40.2
    • If those were intentional, you can disregard the above warnings; however it is recommended to use "git" directly to perform update checks and upgrades.

[!] Android toolchain - develop for Android devices (Android SDK version 35.0.0)
    • Android SDK at /Users/bquinlan/Library/Android/sdk
    ✗ cmdline-tools component is missing
      Run `path/to/sdkmanager --install "cmdline-tools;latest"`
      See https://developer.android.com/studio/command-line for more details.
    ✗ Android license status unknown.
      Run `flutter doctor --android-licenses` to accept the SDK licenses.
      See https://flutter.dev/to/macos-android-setup for more details.

[✓] Xcode - develop for iOS and macOS (Xcode 16.1)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 16B40
    • CocoaPods version 1.16.2

[✓] Chrome - develop for the web
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2024.2)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • Java version OpenJDK Runtime Environment (build 21.0.3+-79915917-b509.11)

[✓] VS Code (version 1.96.4)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.102.0

[✓] Connected device (5 available)
    • Brian’s iPhone (mobile)         • 00008140-0000795E2093C01C            • ios            • iOS 18.1.1 22B91
    • iPhone 15 (mobile)              • 1E351645-1116-4E39-B2C9-BB705CCF3E44 • ios            • com.apple.CoreSimulator.SimRuntime.iOS-17-0 (simulator)
    • macOS (desktop)                 • macos                                • darwin-arm64   • macOS 15.2 24C101 darwin-arm64
    • Mac Designed for iPad (desktop) • mac-designed-for-ipad                • darwin         • macOS 15.2 24C101 darwin-arm64
    • Chrome (web)                    • chrome                               • web-javascript • Google Chrome 132.0.6834.112

[✓] Network resources
    • All expected network resources are available.

! Doctor found issues in 2 categories.

@chenfisher and @martyfuhry - could you include the output of flutter doctor -v? Maybe there is an issue with different Flutter versions.

@frank-applab
Copy link

frank-applab commented Feb 20, 2025

I have the same problem too. It doesn't work on a physical device and also not in the simulator (iPhone 16 Pro Max). v1.5.1 helps at the moment.

[✓] Flutter (Channel stable, 3.29.0, on macOS 15.3 24D60 darwin-arm64, locale de-DE) [484ms]
    • Flutter version 3.29.0 on channel stable at /Users/stonie/Documents/Development/flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision 35c388afb5 (vor 10 Tagen), 2025-02-10 12:48:41 -0800
    • Engine revision f73bfc4522
    • Dart version 3.7.0
    • DevTools version 2.42.2

[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0) [2,9s]
    • Android SDK at /Users/stonie/Library/Android/sdk
    • Platform android-34, build-tools 34.0.0
    • ANDROID_SDK_ROOT = /Users/stonie/Library/Android/sdk
    • Java binary at: /Applications/Android Studio.app/Contents/jbr/Contents/Home/bin/java
      This is the JDK bundled with the latest Android Studio installation on this machine.
      To manually set the JDK path, use: `flutter config --jdk-dir="path/to/jdk"`.
    • Java version OpenJDK Runtime Environment (build 17.0.11+0-17.0.11b1207.24-11852314)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 16.2) [1.068ms]
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Build 16C5032a
    • CocoaPods version 1.16.2

[✓] Chrome - develop for the web [17ms]
    • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[✓] Android Studio (version 2024.1) [16ms]
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/9212-flutter
    • Dart plugin can be installed from:
      🔨 https://plugins.jetbrains.com/plugin/6351-dart
    • android-studio-dir = /Applications/Android Studio.app
    • Java version OpenJDK Runtime Environment (build 17.0.11+0-17.0.11b1207.24-11852314)

[✓] VS Code (version 1.97.2) [14ms]
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.104.0

[✓] Connected device (4 available) [6,5s]
    • Franks iPhone (mobile)                • 00008140-000A2830140B001C            • ios            • iOS 18.3.1 22D72
    • iPhone 16 Pro Max - iOS 18.0 (mobile) • 91651694-E52D-4441-97FE-4CDF0084DED3 • ios            • com.apple.CoreSimulator.SimRuntime.iOS-18-0 (simulator)
    • Mac Designed for iPad (desktop)       • mac-designed-for-ipad                • darwin         • macOS 15.3 24D60 darwin-arm64
    • Chrome (web)                          • chrome                               • web-javascript • Google Chrome 131.0.6778.86

[✓] Network resources [282ms]
    • All expected network resources are available.

• No issues found!

@mraleph
Copy link
Member

mraleph commented Feb 20, 2025

@frank-applab Can you provide more details about the requests you make? Is it .get, .post, etc? Does the simplest client.get(Uri.parse('https://google.com')) never complete like in the original report? Do you have anything peculiar about how you create HTTP client (do you keep it in a global variable or create a new one for each request? etc), or the way you embed Flutter or configure the Flutter app? Do you use Add2App? Do you use isolates? etc. Try to provide as much details as you think is possible because @brianquinlan was unable to reproduce this so far.

@frank-applab
Copy link

It's a native flutter app and I make a simple request. The follow request never complete.

import 'package:dio/dio.dart';
import 'package:native_dio_adapter/native_dio_adapter.dart';

Future<void> main() async {
  WidgetsFlutterBinding.ensureInitialized();

  Dio dio = Dio();
  dio.httpClientAdapter = NativeAdapter();
  await dio.get('https://www.google.com');
}

@brianquinlan
Copy link
Collaborator

Hi @frank-applab

Thats for the additional information! Would it be possible for you to test a unreleased version of cupertino_http for us? You'd just have to modify the pubspec.yaml for your example application.

@frank-applab
Copy link

frank-applab commented Feb 20, 2025

When I create a new project it works.

What I've found out so far as workaround. In my case I have to remove firebase_performance: ^0.10.1+3 from pubspec.yaml in my existing project. All related entries must also be removed from project.pbxproj. Then it works with v.2.0.2.

Remove all entries from project.pbxproj

  • firebase_performance
  • firebasePerformance
  • FirebaseABTesting
  • FirebaseRemoteConfig
  • FirebaseSharedSwift

@brianquinlan
Copy link
Collaborator

brianquinlan commented Feb 20, 2025

package:firebase_performance tracks HTTP calls made through NSURLSession, which is what package:cupertino_http uses. This is a great clue, thank you so much @frank-applab !!!

@brianquinlan
Copy link
Collaborator

I can reproduce this with package:firebase_performance configured with flutter run on both a real device and in the emulator.

Looking into why this is happening...

@brianquinlan
Copy link
Collaborator

Wow, firebase is doing some interesting things: https://github.com/firebase/firebase-ios-sdk/blob/d03362a0d1f3d519bf4fd3597c7bda4a3ccaff06/FirebasePerformance/Sources/Instrumentation/Network/FPRNSURLSessionInstrument.h#L19

Swizzling?

Yep, our current hypothesis is that the way that delegate methods are swizzled is not compatible with the NSProxy approach used by package:objective_c.

FWIW, disabling firebase performance instrumentation resolves the issue for me:
Image

@brianquinlan
Copy link
Collaborator

I managed to create a pure Objective-C reproduction and filed an issue with the Firebase team:
firebase/firebase-ios-sdk#14478

@vincevargadev
Copy link

For what it's worth, the app I'm working on doesn't use firebase_performance, but our iOS app hang with latest version of cupertino_http.

We are using cupertino_http indirectly with native_dio_adapter, and we had to pin its version

  # Newer versions of native_dio_adapter use cupertino_http 2.0.0,
  # which we don't want as it causes the app to hang:
  # https://github.com/dart-lang/http/issues/1702#issuecomment-2616136229
  # The latest version of cupertino_http that still works is 1.5.1,
  # because that is still using and older, functional version of cupertino_http library.
  # cupertino_http 2.0.0 was introduced to native_dio_adapter in 1.4.0,
  # so we need to pin it to 1.3.0
  # https://pub.dev/packages/native_dio_adapter/changelog#140
  native_dio_adapter: 1.3.0

@asaarnak
Copy link

We updated to cupertino_http: ^2.1.0 and we use both native_dio_adapter and firebase_performance and it works now.

@vincevargadev
Copy link

cupertino_http: ^2.1.0 seems to work for us, too!

@brianquinlan
Copy link
Collaborator

Thanks for the feedback!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
package:cupertino_http Issues related to package:cupertino_http type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)
Projects
None yet
Development

No branches or pull requests

8 participants