Peter
Peter

Reputation: 859

Not able to record Jmeter requests of Flutter app

I have tried existing answers but didn't succeed. I have tried with HTTP(S) Test Script Recorder of Jmeter and I am not able to capture Application requests of my apk in Jmeter while I am able to get some connectivity check requests such as 'connectivitycheck.gstatic.com' and 'www.google.com'.

I have also tried using blazemeter as well (https://guide.blazemeter.com/hc/en-us/articles/13354685999889) but didn't captured. Using that I am able to captures all the requests from Phone's browser but NOT application requests.

I am using Jmeter Ver. 5.5, Android Emulator with API 34 x86_64. Thanks a lot. enter image description here

Upvotes: 1

Views: 303

Answers (2)

anzvanie
anzvanie

Reputation: 43

Root cause: Flutter uses Dart which is not proxy-aware

The primary reason JMeter cannot record requests from your mobile app to the server is that Flutter uses Dart, which is not proxy-aware.
JMeter operates by creating a proxy server, through which your mobile app connects to the internet. This setup allows JMeter to capture and record the requests sent by the mobile app.
However, by default, Flutter apps do not use the proxy server configured in the system settings. As a result, configuring the proxy as instructed will have no effect on Flutter apps.

Solution

The simple solution is to explicitly configure the proxy server for the Flutter app, in addition to following the general instructions. Below is a guide for using popular libraries to connect to the server in Flutter.

http

  1. Add the following libraries

    flutter pub add http
    flutter pub add system_proxy
    
  2. Retrieve the system proxy and configure it for the Flutter app

    class ProxiedHttpOverrides extends HttpOverrides {
        final String _port;
        final String _host;
        ProxiedHttpOverrides(this._host, this._port);
    
        @override
        HttpClient createHttpClient(SecurityContext? context) {
            return super.createHttpClient(context)
            // set proxy
            ..findProxy = (uri) {
                return 'PROXY $_host:$_port';
            }
            ..badCertificateCallback = (X509Certificate cert, String host, int port) => true;
        }
    }
    
    
    void main() async {
        WidgetsFlutterBinding.ensureInitialized();
    
        Map<String, String>? proxy = await SystemProxy.getProxySettings();
        if (proxy != null) {
            HttpOverrides.global = ProxiedHttpOverrides(proxy['host']!, proxy['port']!);
        }
    
        runApp(MyApp());
    }
    

    Note: The following line of code is required for using the self-signed certificates generated by JMeter

    ..badCertificateCallback = (X509Certificate cert, String host, int port) => true;
    
  3. Perform a request from the mobile app to the API

    const url = 'https://petstore.swagger.io/v2/pet/findByStatus?status=available';
    await http.get(Uri.parse(url));
    

dio

  1. Add the following libraries

    flutter pub add dio
    flutter pub add system_proxy
    
  2. Retrieve the system proxy and configure it for the Flutter app

    class ProxiedHttpOverrides extends HttpOverrides {
        final String _port;
        final String _host;
        ProxiedHttpOverrides(this._host, this._port);
    
        @override
        HttpClient createHttpClient(SecurityContext? context) {
            return super.createHttpClient(context)
            // set proxy
            ..findProxy = (uri) {
                return 'PROXY $_host:$_port';
            }
            ..badCertificateCallback = (X509Certificate cert, String host, int port) => true;
        }
    }
    
    void main() async {
        WidgetsFlutterBinding.ensureInitialized();
    
        Map<String, String>? proxy = await SystemProxy.getProxySettings();
        if (proxy != null) {
            final httpOverrides = ProxiedHttpOverrides(proxy['host']!, proxy['port']!);
    
            dio.httpClientAdapter = IOHttpClientAdapter()
                ..createHttpClient = () {
                    return httpOverrides.createHttpClient(null);
                };
        }
    
        runApp(MyApp());
    }
    

    Note: The following line of code is required for using the self-signed certificates generated by JMeter

    ..badCertificateCallback = (X509Certificate cert, String host, int port) => true;
    
  3. Perform a request from the mobile app to the API

    const url = 'https://petstore.swagger.io/v2/pet/findByStatus?status=available';
    await dio.get(url);
    

Upvotes: 0

Dmitri T
Dmitri T

Reputation: 168147

  1. Are you sure you're setting the proxy in correct place? Emulator has its own proxy settings:

    enter image description here

  2. Check jmeter.log file for any suspicious entries (it will be a good idea to enable JMeter debug logging for the HTTP(S) Test Script Recorder)

  3. Both HTTP(S) Test Script Recorder and BlazeMeter Proxy Recorder are only capable of capturing HTTP or HTTPS traffic, if your application uses other network protocol(s) you will have to find another way of intercepting requests like using a sniffer tool

Upvotes: 0

Related Questions