Skip to content

Commit ec1fe6c

Browse files
committed
Add flutter request button
1 parent d3e5e2c commit ec1fe6c

File tree

14 files changed

+559
-3
lines changed

14 files changed

+559
-3
lines changed

.idea/compiler.xml

Lines changed: 4 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/gradle.xml

Lines changed: 13 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/build.gradle

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ def keyStorePassword = System.getenv('KEYSTORE_PASSWORD')
77
def keyAvailable = !!keyStorePassword
88

99
android {
10-
compileSdkVersion 33
10+
compileSdkVersion 35
1111

1212
defaultConfig {
1313
applicationId "tech.httptoolkit.pinning_demo"
@@ -64,4 +64,6 @@ dependencies {
6464
implementation 'androidx.preference:preference-ktx:1.1.1'
6565
implementation 'com.appmattus.certificatetransparency:certificatetransparency-android:2.5.18'
6666
implementation 'org.chromium.net:cronet-embedded:119.6045.31'
67+
68+
implementation project(':flutter')
6769
}

app/src/main/java/tech/httptoolkit/pinning_demo/MainActivity.kt

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ import com.appmattus.certificatetransparency.certificateTransparencyInterceptor
2020
import com.appmattus.certificatetransparency.certificateTransparencyTrustManager
2121
import com.appmattus.certificatetransparency.installCertificateTransparencyProvider
2222
import com.datatheorem.android.trustkit.TrustKit
23+
import io.flutter.embedding.engine.FlutterEngine
24+
import io.flutter.embedding.engine.dart.DartExecutor
25+
import io.flutter.plugin.common.MethodChannel
2326
import kotlinx.coroutines.DelicateCoroutinesApi
2427
import kotlinx.coroutines.Dispatchers
2528
import kotlinx.coroutines.GlobalScope
@@ -49,6 +52,9 @@ const val LETS_ENCRYPT_R3_INTERM_PK_SHA256 = "jQJTbIh0grw0/1TkHSumWb+Fs0Ggogr621
4952
@Suppress("UNUSED_PARAMETER")
5053
@DelicateCoroutinesApi
5154
class MainActivity : AppCompatActivity() {
55+
56+
private var flutterEngine: FlutterEngine? = null
57+
5258
override fun onCreate(savedInstanceState: Bundle?) {
5359
super.onCreate(savedInstanceState)
5460
setContentView(R.layout.activity_main)
@@ -62,6 +68,17 @@ class MainActivity : AppCompatActivity() {
6268
-"*.badssl.com"
6369
+"rsa4096.badssl.com"
6470
}
71+
72+
// Prepare the flutter engine:
73+
flutterEngine = FlutterEngine(this)
74+
flutterEngine!!.dartExecutor.executeDartEntrypoint(
75+
DartExecutor.DartEntrypoint.createDefault()
76+
)
77+
}
78+
79+
override fun onDestroy() {
80+
super.onDestroy()
81+
flutterEngine?.destroy()
6582
}
6683

6784
private fun onStart(@IdRes id: Int) {
@@ -478,6 +495,29 @@ class MainActivity : AppCompatActivity() {
478495
}
479496
}
480497

498+
fun sendFlutterRequest(view: View) {
499+
onStart(R.id.flutter_request)
500+
501+
val channel = MethodChannel(flutterEngine!!.dartExecutor.binaryMessenger, "tech.httptoolkit.pinning_demo.flutter_channel")
502+
503+
println("Calling Dart method from Kotlin...")
504+
channel.invokeMethod("sendRequest", "https://ecc384.badssl.com/", object : MethodChannel.Result {
505+
override fun success(result: Any?) {
506+
println("Success from Dart: $result")
507+
onSuccess(R.id.flutter_request)
508+
}
509+
510+
override fun error(errorCode: String, errorMessage: String?, errorDetails: Any?) {
511+
println("Error: $errorCode - $errorMessage")
512+
onError(R.id.flutter_request, errorMessage ?: "Unknown error")
513+
}
514+
515+
override fun notImplemented() {
516+
println("Method not implemented on Dart side.")
517+
}
518+
})
519+
}
520+
481521
// Manually pinned at the lowest level: creating a raw TLS connection, disabling all checks,
482522
// and then directly analysing the certificate that's received after connection, before doing
483523
// HTTP by just writing & reading raw strings. Not a good idea, but the hardest to unpin!

app/src/main/res/layout/activity_main.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,13 @@
121121
android:layout_marginBottom="10dp"
122122
android:background="@android:color/darker_gray"/>
123123

124+
<Button
125+
android:id="@+id/flutter_request"
126+
android:layout_width="match_parent"
127+
android:layout_height="wrap_content"
128+
android:onClick="sendFlutterRequest"
129+
android:text="Flutter request" />
130+
124131
<Button
125132
android:id="@+id/custom_raw_socket_pinned"
126133
android:layout_width="match_parent"

flutter_module/.gitignore

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
.DS_Store
2+
.dart_tool/
3+
4+
.pub/
5+
6+
.idea/
7+
.vagrant/
8+
.sconsign.dblite
9+
.svn/
10+
11+
migrate_working_dir/
12+
13+
*.swp
14+
profile
15+
16+
DerivedData/
17+
18+
.generated/
19+
20+
*.pbxuser
21+
*.mode1v3
22+
*.mode2v3
23+
*.perspectivev3
24+
25+
!default.pbxuser
26+
!default.mode1v3
27+
!default.mode2v3
28+
!default.perspectivev3
29+
30+
xcuserdata
31+
32+
*.moved-aside
33+
34+
*.pyc
35+
*sync/
36+
Icon?
37+
.tags*
38+
39+
build/
40+
.android/
41+
.ios/
42+
.flutter-plugins
43+
.flutter-plugins-dependencies
44+
45+
# Symbolication related
46+
app.*.symbols
47+
48+
# Obfuscation related
49+
app.*.map.json

flutter_module/.metadata

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# This file tracks properties of this Flutter project.
2+
# Used by Flutter tool to assess capabilities and perform upgrades etc.
3+
#
4+
# This file should be version controlled and should not be manually edited.
5+
6+
version:
7+
revision: "fcf2c11572af6f390246c056bc905eca609533a0"
8+
channel: "stable"
9+
10+
project_type: module

flutter_module/README.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# flutter_module
2+
3+
A new Flutter module project.
4+
5+
## Getting Started
6+
7+
For help getting started with Flutter development, view the online
8+
[documentation](https://flutter.dev/).
9+
10+
For instructions integrating Flutter modules to your existing applications,
11+
see the [add-to-app documentation](https://flutter.dev/to/add-to-app).

flutter_module/analysis_options.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
include: package:flutter_lints/flutter.yaml
2+
3+
# Additional information about this file can be found at
4+
# https://dart.dev/guides/language/analysis-options

flutter_module/lib/main.dart

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import 'dart:developer' as developer;
2+
import 'package:flutter/services.dart';
3+
import 'package:flutter/widgets.dart';
4+
import 'package:http/http.dart' as http;
5+
6+
void main() {
7+
const MethodChannel channel = MethodChannel('tech.httptoolkit.pinning_demo.flutter_channel');
8+
WidgetsFlutterBinding.ensureInitialized();
9+
10+
channel.setMethodCallHandler((call) async {
11+
if (call.method == 'sendRequest') {
12+
final urlString = call.arguments as String?;
13+
if (urlString == null || urlString.isEmpty) {
14+
throw PlatformException(
15+
code: 'INVALID_ARGUMENT',
16+
message: 'URL argument is null or empty.',
17+
);
18+
}
19+
20+
developer.log('Dart attempting to send request to: $urlString', name: 'Flutter SendRequest');
21+
22+
try {
23+
final url = Uri.parse(urlString);
24+
final response = await http.get(url);
25+
developer.log('Got 200 response: ${response.statusCode}', name: 'Flutter SendRequest');
26+
return 'success';
27+
} on http.ClientException catch (e) {
28+
developer.log('Request completed with a non-2xx status code.', name: 'Flutter SendRequest', error: e);
29+
return 'success'; // We don't care about status codes
30+
} catch (e, stackTrace) {
31+
// Any other error:
32+
developer.log(
33+
'A network or parsing error occurred.',
34+
name: 'Flutter SendRequest',
35+
error: e,
36+
stackTrace: stackTrace,
37+
);
38+
throw PlatformException(
39+
code: 'NETWORK_ERROR',
40+
message: 'Failed to send request: ${e.toString()}',
41+
);
42+
}
43+
}
44+
developer.log('Unknown method call ${call.method}', name: 'Flutter');
45+
});
46+
}

0 commit comments

Comments
 (0)