Skip to content

Commit c3c77f4

Browse files
authored
Merge pull request #360 from Countly/headers_after_init
Change network headers after init
2 parents de85cb4 + c753e42 commit c3c77f4

File tree

5 files changed

+85
-3
lines changed

5 files changed

+85
-3
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
## XX.XX.XX
2+
* Added a new function "addCustomNetworkRequestHeaders: customHeaderValues" for providing or overriding custom headers after init.
23
* Default request method is now set to "POST"
34

45
## 25.4.1

android/src/main/java/ly/count/dart/countly_flutter/CountlyFlutterPlugin.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -337,8 +337,11 @@ else if ("getID".equals(call.method)) {
337337
else if ("attemptToSendStoredRequests".equals(call.method)) {
338338
Countly.sharedInstance().requestQueue().attemptToSendStoredRequests();
339339
result.success("attemptToSendStoredRequests success!");
340-
}
341-
else if ("setHttpPostForced".equals(call.method)) {
340+
} else if ("addCustomNetworkRequestHeaders".equals(call.method)) {
341+
Map<String, String> customHeaderValues = toMapString(args.getJSONObject(0));
342+
Countly.sharedInstance().requestQueue().addCustomNetworkRequestHeaders(customHeaderValues);
343+
result.success("addCustomNetworkRequestHeaders success!");
344+
} else if ("setHttpPostForced".equals(call.method)) {
342345
boolean isEnabled = args.getBoolean(0);
343346
this.config.setHttpPostForced(isEnabled);
344347
result.success("setHttpPostForced");
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import 'dart:io';
2+
import 'dart:math';
3+
4+
import 'package:countly_flutter/countly_flutter.dart';
5+
import 'package:flutter_test/flutter_test.dart';
6+
import 'package:integration_test/integration_test.dart';
7+
8+
import '../utils.dart';
9+
10+
/**
11+
* Tests for adding custom network request headers before and after SDK initialization.
12+
* Verifies that the headers are correctly sent with network requests.
13+
* Covers scenarios of initial headers set during config and additional headers added later.
14+
* Checks for header overriding and empty header values.
15+
* Uses a local test server to capture and validate request headers.
16+
*/
17+
void main() {
18+
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
19+
testWidgets('addCustomNetworkRequestHeaders_test', (WidgetTester tester) async {
20+
List<HttpHeaders> headersArray = <HttpHeaders>[];
21+
createServer(
22+
<Map<String, List<String>>>[],
23+
customHandler: (req, res) async {
24+
// Print request headers for debugging
25+
headersArray.add(req.headers);
26+
},
27+
);
28+
// Initialize the SDK
29+
CountlyConfig config = CountlyConfig("http://0.0.0.0:8080", APP_KEY).enableManualSessionHandling().setLoggingEnabled(true);
30+
config.setCustomNetworkRequestHeaders({"Initial-Header": "InitialValue"});
31+
await Countly.initWithConfig(config);
32+
await Future.delayed(const Duration(seconds: 1));
33+
for (var headers in headersArray) {
34+
expect('InitialValue', headers.value('Initial-Header'));
35+
expect(null, headers.value('X-Custom-Header-1'));
36+
expect(null, headers.value('X-Custom-Header-2'));
37+
expect(null, headers.value('X-Custom-Header-3'));
38+
}
39+
headersArray.clear();
40+
// Add custom headers
41+
await Countly.instance.addCustomNetworkRequestHeaders({"X-Custom-Header-1": "", "": "CustomValue2", "X-Custom-Header-3": "CustomValue3", "Initial-Header": "OverriddenValue"});
42+
// Make a request to trigger headers being sent
43+
await Countly.instance.sessions.beginSession();
44+
await Future.delayed(const Duration(seconds: 2));
45+
46+
for (var headers in headersArray) {
47+
expect('OverriddenValue', headers.value('Initial-Header'));
48+
expect('', headers.value('X-Custom-Header-1'));
49+
expect(null, headers.value(''));
50+
expect('CustomValue3', headers.value('X-Custom-Header-3'));
51+
}
52+
});
53+
}

ios/Classes/CountlyFlutterPlugin.m

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1390,7 +1390,13 @@ - (void)handleMethodCall:(FlutterMethodCall *)call result:(FlutterResult)result
13901390
[Countly.sharedInstance attemptToSendStoredRequests];
13911391
});
13921392
result(@"attemptToSendStoredRequests: success");
1393-
} else {
1393+
} else if ([@"addCustomNetworkRequestHeaders" isEqualToString:call.method]) {
1394+
dispatch_async(dispatch_get_main_queue(), ^{
1395+
NSDictionary* customHeaderValues = [command objectAtIndex:0];
1396+
[Countly.sharedInstance addCustomNetworkRequestHeaders:customHeaderValues];
1397+
result(nil);
1398+
});
1399+
} else {
13941400
result(FlutterMethodNotImplemented);
13951401
}
13961402
}

lib/src/countly_flutter.dart

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1692,6 +1692,25 @@ class Countly {
16921692
await _channel.invokeMethod('attemptToSendStoredRequests');
16931693
}
16941694

1695+
/// Add custom headers to all network requests made by the SDK.
1696+
Future<void> addCustomNetworkRequestHeaders(Map<String, String> customHeaderValues) async {
1697+
if (!_instance._countlyState.isInitialized) {
1698+
log('addCustomNetworkRequestHeaders, "initWithConfig" must be called before "addCustomNetworkRequestHeaders"', logLevel: LogLevel.ERROR);
1699+
return;
1700+
}
1701+
1702+
if (customHeaderValues.isEmpty) {
1703+
log('addCustomNetworkRequestHeaders, customHeaderValues cannot be empty', logLevel: LogLevel.WARNING);
1704+
return;
1705+
}
1706+
1707+
log('Calling "addCustomNetworkRequestHeaders" with headers count: [${customHeaderValues.length}]');
1708+
List<dynamic> args = [];
1709+
args.add(customHeaderValues);
1710+
1711+
await _channel.invokeMethod('addCustomNetworkRequestHeaders', <String, dynamic>{'data': json.encode(args)});
1712+
}
1713+
16951714
/// starts a timed event
16961715
/// returns error or success message
16971716
@Deprecated('This function is deprecated, please use "startEvent" of events instead')

0 commit comments

Comments
 (0)