Skip to content

Commit c24ddd9

Browse files
ahmed1hishamAli AbdelfattahMahmoudMehisen
authored
[MOB-5938] Fix response payload size (#202)
* Fix response payload size * Update CHANGELOG.md * Fix android payload sizes * Add try catch wrapper to Android APMNetworkLogger * Fix requestHeaders in http client logger * Fix requestBody and requestBodySize in http client logger * Fix network contentType header logging * Fix iOS network logger contentType value * Update CHANGELOG.md Co-authored-by: Ali Abdelfattah <[email protected]> * Add test coverage for InstabugCustomHttpClientRequest * Add test coverage for NetworkLogger * Add changes to APM network log api * Add changes to iOS network log api Co-authored-by: Ali Abdelfattah <[email protected]> Co-authored-by: MahmoudMehisen <[email protected]>
1 parent 60b8ec0 commit c24ddd9

12 files changed

+551
-129
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
* Adds APM.endAppLaunch API
44
* Bumps Instabug native SDKs to v10.11
5+
* Fixes an issue with logged requests payload size
56

67
## v10.9.1 (2021-10-13)
78

android/src/main/java/com/instabug/instabugflutter/InstabugFlutterPlugin.java

Lines changed: 48 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1148,41 +1148,57 @@ public void run() {
11481148
}
11491149

11501150
public void apmNetworkLogByReflection(HashMap<String, Object> jsonObject) throws JSONException {
1151-
APMNetworkLogger apmNetworkLogger = new APMNetworkLogger();
1152-
final String requestUrl = (String) jsonObject.get("url");
1153-
final String requestBody = (String) jsonObject.get("requestBody");
1154-
final String responseBody = (String) jsonObject.get("responseBody");
1155-
final String requestMethod = (String) jsonObject.get("method");
1156-
//--------------------------------------------
1157-
final String requestContentType = (String) jsonObject.get("contentType");
1158-
final String responseContentType = (String) jsonObject.get("responseContentType");
1159-
//--------------------------------------------
1160-
final String errorDomain = (String) jsonObject.get("errorDomain");
1161-
final Integer statusCode = (Integer) jsonObject.get("responseCode");
1162-
final long requestDuration = ((Number) jsonObject.get("duration")).longValue() / 1000;
1163-
final long requestStartTime = ((Number) jsonObject.get("startTime")).longValue() * 1000;
1164-
final String requestHeaders = (new JSONObject((HashMap<String, String>) jsonObject.get("requestHeaders"))).toString(4);
1165-
final String responseHeaders = (new JSONObject((HashMap<String, String>) jsonObject.get("responseHeaders"))).toString(4);
1166-
final String errorMessage;
1167-
1168-
if(errorDomain.equals("")) {
1169-
errorMessage = null;
1170-
} else {
1171-
errorMessage = errorDomain;
1172-
}
1173-
11741151
try {
1175-
Method method = getMethod(Class.forName("com.instabug.apm.networking.APMNetworkLogger"), "log", long.class, long.class, String.class, String.class, String.class, String.class, String.class, String.class, String.class, int.class, String.class, String.class);
1176-
if (method != null) {
1177-
method.invoke(apmNetworkLogger, requestStartTime, requestDuration, requestHeaders, requestBody, requestMethod, requestUrl, requestContentType, responseHeaders, responseBody, statusCode, responseContentType, errorMessage);
1152+
APMNetworkLogger apmNetworkLogger = new APMNetworkLogger();
1153+
final String requestUrl = (String) jsonObject.get("url");
1154+
final String requestBody = (String) jsonObject.get("requestBody");
1155+
final String responseBody = (String) jsonObject.get("responseBody");
1156+
final String requestMethod = (String) jsonObject.get("method");
1157+
//--------------------------------------------
1158+
final String requestContentType = (String) jsonObject.get("requestContentType");
1159+
final String responseContentType = (String) jsonObject.get("responseContentType");
1160+
//--------------------------------------------
1161+
final long requestBodySize = ((Number) jsonObject.get("requestBodySize")).longValue();
1162+
final long responseBodySize = ((Number) jsonObject.get("responseBodySize")).longValue();
1163+
//--------------------------------------------
1164+
final String errorDomain = (String) jsonObject.get("errorDomain");
1165+
final Integer statusCode = (Integer) jsonObject.get("responseCode");
1166+
final long requestDuration = ((Number) jsonObject.get("duration")).longValue() / 1000;
1167+
final long requestStartTime = ((Number) jsonObject.get("startTime")).longValue() * 1000;
1168+
final String requestHeaders = (new JSONObject((HashMap<String, String>) jsonObject.get("requestHeaders"))).toString(4);
1169+
final String responseHeaders = (new JSONObject((HashMap<String, String>) jsonObject.get("responseHeaders"))).toString(4);
1170+
final String errorMessage;
1171+
1172+
if(errorDomain.equals("")) {
1173+
errorMessage = null;
11781174
} else {
1179-
Log.e("IB-CP-Bridge", "apmNetworkLogByReflection was not found by reflection");
1175+
errorMessage = errorDomain;
11801176
}
1181-
} catch (ClassNotFoundException e) {
1182-
e.printStackTrace();
1183-
} catch (IllegalAccessException e) {
1184-
e.printStackTrace();
1185-
} catch (InvocationTargetException e) {
1177+
//--------------------------------------------------
1178+
String gqlQueryName = null;
1179+
if(jsonObject.containsKey("gqlQueryName")){
1180+
gqlQueryName = (String) jsonObject.get("gqlQueryName");
1181+
}
1182+
String serverErrorMessage = "";
1183+
if(jsonObject.containsKey("serverErrorMessage")){
1184+
serverErrorMessage = (String) jsonObject.get("serverErrorMessage");
1185+
}
1186+
1187+
try {
1188+
Method method = getMethod(Class.forName("com.instabug.apm.networking.APMNetworkLogger"), "log", long.class, long.class, String.class, String.class, long.class, String.class, String.class, String.class, String.class, String.class, long.class, int.class, String.class, String.class, String.class, String.class);
1189+
if (method != null) {
1190+
method.invoke(apmNetworkLogger, requestStartTime, requestDuration, requestHeaders, requestBody, requestBodySize, requestMethod, requestUrl, requestContentType, responseHeaders, responseBody, responseBodySize, statusCode, responseContentType, errorMessage, gqlQueryName, serverErrorMessage);
1191+
} else {
1192+
Log.e("IB-CP-Bridge", "apmNetworkLogByReflection was not found by reflection");
1193+
}
1194+
} catch (ClassNotFoundException e) {
1195+
e.printStackTrace();
1196+
} catch (IllegalAccessException e) {
1197+
e.printStackTrace();
1198+
} catch (InvocationTargetException e) {
1199+
e.printStackTrace();
1200+
}
1201+
} catch (Exception e) {
11861202
e.printStackTrace();
11871203
}
11881204

example/android/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
buildscript {
2-
ext.kotlin_version = '1.3.50'
2+
ext.kotlin_version = '1.4.32'
33
repositories {
44
google()
55
jcenter()

ios/Classes/InstabugFlutterPlugin.m

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -766,7 +766,7 @@ + (void)networkLog:(NSDictionary *) networkData {
766766
requestHeaders = @{};
767767
}
768768
NSDictionary* responseHeaders = networkData[@"responseHeaders"];
769-
NSString* contentType = @"application/json";
769+
NSString* contentType = networkData[@"responseContentType"];
770770
int64_t duration = [networkData[@"duration"] integerValue];
771771
int64_t startTime = [networkData[@"startTime"] integerValue] * 1000;
772772

@@ -775,7 +775,16 @@ + (void)networkLog:(NSDictionary *) networkData {
775775
NSLog(@"value: %@",[requestHeaders objectForKey:key]);
776776
}
777777

778-
SEL networkLogSEL = NSSelectorFromString(@"addNetworkLogWithUrl:method:requestBody:requestBodySize:responseBody:responseBodySize:responseCode:requestHeaders:responseHeaders:contentType:errorDomain:errorCode:startTime:duration:");
778+
NSString* gqlQueryName = nil;
779+
NSString* serverErrorMessage = nil;
780+
if (networkData[@"gqlQueryName"] != [NSNull null]) {
781+
gqlQueryName = networkData[@"gqlQueryName"];
782+
}
783+
if (networkData[@"serverErrorMessage"] != [NSNull null]) {
784+
serverErrorMessage = networkData[@"serverErrorMessage"];
785+
}
786+
787+
SEL networkLogSEL = NSSelectorFromString(@"addNetworkLogWithUrl:method:requestBody:requestBodySize:responseBody:responseBodySize:responseCode:requestHeaders:responseHeaders:contentType:errorDomain:errorCode:startTime:duration:gqlQueryName:serverErrorMessage:");
779788

780789
if([[IBGNetworkLogger class] respondsToSelector:networkLogSEL]) {
781790
NSInvocation *inv = [NSInvocation invocationWithMethodSignature:[[IBGNetworkLogger class] methodSignatureForSelector:networkLogSEL]];
@@ -796,6 +805,8 @@ + (void)networkLog:(NSDictionary *) networkData {
796805
[inv setArgument:&(errorCode) atIndex:13];
797806
[inv setArgument:&(startTime) atIndex:14];
798807
[inv setArgument:&(duration) atIndex:15];
808+
[inv setArgument:&(gqlQueryName) atIndex:16];
809+
[inv setArgument:&(serverErrorMessage) atIndex:17];
799810

800811
[inv invoke];
801812
}

lib/NetworkLogger.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class NetworkLogger {
1212
static Future<String?> get platformVersion async =>
1313
await _channel.invokeMethod<String>('getPlatformVersion');
1414

15-
static Future<bool?> networkLog(NetworkData data) async {
15+
Future<bool?> networkLog(NetworkData data) async {
1616
final params = <dynamic>[data.toMap()];
1717
await _channel.invokeMethod<bool>('networkLog:', params);
1818
await APM.networkLogAndroid(data);

lib/instabug_custom_http_client_request.dart

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ class InstabugCustomHttpClientRequest implements HttpClientRequest {
1515

1616
HttpClientRequest _originalClientRequest;
1717

18+
StringBuffer _requestBody = StringBuffer();
19+
1820
late HttpClientLogger logger;
1921

2022
@override
@@ -89,20 +91,32 @@ class InstabugCustomHttpClientRequest implements HttpClientRequest {
8991
@override
9092
void write(Object? object) {
9193
_originalClientRequest.write(object);
94+
_requestBody.write(object);
95+
logger.onRequestUpdate(_originalClientRequest,
96+
requestBody: _requestBody.toString());
9297
}
9398

9499
@override
95-
void writeAll(Iterable objects, [String separator = ""]) {
100+
void writeAll(Iterable objects, [String separator = '']) {
96101
_originalClientRequest.writeAll(objects, separator);
102+
_requestBody.writeAll(objects, separator);
103+
logger.onRequestUpdate(_originalClientRequest,
104+
requestBody: _requestBody.toString());
97105
}
98106

99107
@override
100108
void writeCharCode(int charCode) {
101109
_originalClientRequest.writeCharCode(charCode);
110+
_requestBody.writeCharCode(charCode);
111+
logger.onRequestUpdate(_originalClientRequest,
112+
requestBody: _requestBody.toString());
102113
}
103114

104115
@override
105-
void writeln([Object? object = ""]) {
116+
void writeln([Object? object = '']) {
106117
_originalClientRequest.writeln(object);
118+
_requestBody.writeln(object);
119+
logger.onRequestUpdate(_originalClientRequest,
120+
requestBody: _requestBody.toString());
107121
}
108122
}

lib/models/network_data.dart

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ class NetworkData {
1010
this.requestHeaders = const <String, dynamic>{},
1111
this.responseHeaders = const <String, dynamic>{},
1212
this.duration,
13-
this.contentType = '',
13+
this.requestContentType = '',
14+
this.responseContentType = '',
1415
this.endTime,
1516
required this.startTime,
1617
this.errorCode = 0,
@@ -26,7 +27,8 @@ class NetworkData {
2627
final Map<String, dynamic> requestHeaders;
2728
final Map<String, dynamic> responseHeaders;
2829
final int? duration;
29-
final String? contentType;
30+
final String? requestContentType;
31+
final String? responseContentType;
3032
final DateTime? endTime;
3133
final DateTime startTime;
3234
final int errorCode;
@@ -43,7 +45,8 @@ class NetworkData {
4345
Map<String, dynamic>? requestHeaders,
4446
Map<String, dynamic>? responseHeaders,
4547
int? duration,
46-
String? contentType,
48+
String? requestContentType,
49+
String? responseContentType,
4750
DateTime? endTime,
4851
DateTime? startTime,
4952
int? errorCode,
@@ -60,7 +63,8 @@ class NetworkData {
6063
requestHeaders: requestHeaders ?? this.requestHeaders,
6164
responseHeaders: responseHeaders ?? this.responseHeaders,
6265
duration: duration ?? this.duration,
63-
contentType: contentType ?? this.contentType,
66+
requestContentType: requestContentType ?? this.requestContentType,
67+
responseContentType: responseContentType ?? this.responseContentType,
6468
endTime: endTime ?? this.endTime,
6569
startTime: startTime ?? this.startTime,
6670
errorCode: errorCode ?? this.errorCode,
@@ -76,7 +80,8 @@ class NetworkData {
7680
map['responseCode'] = status;
7781
map['requestHeaders'] = requestHeaders;
7882
map['responseHeaders'] = responseHeaders;
79-
map['contentType'] = contentType;
83+
map['requestContentType'] = requestContentType;
84+
map['responseContentType'] = responseContentType;
8085
map['duration'] = duration;
8186
map['startTime'] = startTime.millisecondsSinceEpoch;
8287
map['requestBodySize'] = requestBodySize;

lib/utils/http_client_logger.dart

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
import 'dart:convert';
12
import 'dart:io';
23

34
import 'package:instabug_flutter/NetworkLogger.dart';
45
import 'package:instabug_flutter/models/network_data.dart';
56

67
class HttpClientLogger {
78
final requests = <int, NetworkData>{};
9+
var networkLogger = NetworkLogger();
810

911
NetworkData? _getRequestData(int requestHashCode) {
1012
if (requests[requestHashCode] != null) {
@@ -30,29 +32,49 @@ class HttpClientLogger {
3032
requests[request.hashCode] = requestData;
3133
}
3234

35+
void onRequestUpdate(HttpClientRequest request, {dynamic requestBody}) {
36+
final networkData = _getRequestData(request.hashCode);
37+
if (networkData == null) {
38+
return;
39+
}
40+
requests[request.hashCode] = networkData.copyWith(
41+
requestBody: requestBody,
42+
);
43+
}
44+
3345
void onResponse(HttpClientResponse response, HttpClientRequest request,
3446
{dynamic responseBody}) {
3547
final DateTime endTime = DateTime.now();
3648
final networkData = _getRequestData(request.hashCode);
3749
final responseHeaders = <String, dynamic>{};
50+
final requestHeaders = <String, dynamic>{};
3851

3952
if (networkData == null) {
4053
return;
4154
}
4255

43-
request.headers.forEach((String header, dynamic value) {
56+
response.headers.forEach((String header, dynamic value) {
4457
responseHeaders[header] = value[0];
4558
});
59+
request.headers.forEach((String header, dynamic value) {
60+
requestHeaders[header] = value[0];
61+
});
62+
63+
final int requestBodySize =
64+
json.decode(json.encode(networkData.requestBody)).length;
4665

47-
NetworkLogger.networkLog(networkData.copyWith(
66+
networkLogger.networkLog(networkData.copyWith(
4867
status: response.statusCode,
4968
duration: endTime.difference(networkData.startTime).inMicroseconds,
50-
contentType: response.headers.contentType?.value,
69+
responseContentType: response.headers.contentType?.value,
70+
requestContentType: request.headers.contentType?.value,
5171
responseHeaders: responseHeaders,
5272
responseBody: responseBody,
5373
errorCode: 0,
5474
errorDomain: response.statusCode != 0 ? '' : 'ClientError',
5575
responseBodySize: int.parse(responseHeaders['content-length'] ?? '0'),
76+
requestBodySize: requestBodySize,
77+
requestHeaders: requestHeaders,
5678
));
5779
}
5880
}

test/instabug_flutter_test.dart

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,8 @@ void main() {
6666
url: url,
6767
method: method,
6868
startTime: startDate,
69-
contentType: contentType,
69+
requestContentType: contentType,
70+
responseContentType: contentType,
7071
duration: duration,
7172
endTime: endDate,
7273
requestBody: requestBody,
@@ -885,7 +886,8 @@ void main() {
885886
final data =
886887
NetworkData(method: 'method', url: 'url', startTime: DateTime.now());
887888
final List<dynamic> args = <dynamic>[data.toMap()];
888-
NetworkLogger.networkLog(data);
889+
final networkLogger = NetworkLogger();
890+
networkLogger.networkLog(data);
889891
expect(log, <Matcher>[
890892
isMethodCall(
891893
'networkLog:',
@@ -937,7 +939,10 @@ void main() {
937939
final newNetworkData = networkData.toMap();
938940
expect(networkData.url, newNetworkData['url']);
939941
expect(networkData.method, newNetworkData['method']);
940-
expect(networkData.contentType, newNetworkData['contentType']);
942+
expect(
943+
networkData.requestContentType, newNetworkData['requestContentType']);
944+
expect(
945+
networkData.responseContentType, newNetworkData['responseContentType']);
941946
expect(networkData.duration, newNetworkData['duration']);
942947
expect(networkData.requestBody, newNetworkData['requestBody']);
943948
expect(networkData.responseBody, newNetworkData['responseBody']);
@@ -978,7 +983,8 @@ void main() {
978983
responseBody: responseBodyCopy,
979984
responseHeaders: responseHeadersCopy,
980985
duration: durationCopy,
981-
contentType: contentTypeCopy,
986+
requestContentType: contentTypeCopy,
987+
responseContentType: contentTypeCopy,
982988
startTime: startDateCopy,
983989
endTime: endDateCopy,
984990
status: statusCopy);
@@ -990,7 +996,8 @@ void main() {
990996
expect(newNetworkData.responseBody, responseBodyCopy);
991997
expect(newNetworkData.responseHeaders, responseHeadersCopy);
992998
expect(newNetworkData.duration, durationCopy);
993-
expect(newNetworkData.contentType, contentTypeCopy);
999+
expect(newNetworkData.requestContentType, contentTypeCopy);
1000+
expect(newNetworkData.responseContentType, contentTypeCopy);
9941001
expect(newNetworkData.startTime, startDateCopy);
9951002
expect(newNetworkData.endTime, endDateCopy);
9961003
expect(newNetworkData.status, statusCopy);

test/instabug_flutter_test.mocks.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
// Mocks generated by Mockito 5.0.10 from annotations
1+
// Mocks generated by Mockito 5.0.15 from annotations
22
// in instabug_flutter/example/ios/.symlinks/plugins/instabug_flutter/test/instabug_flutter_test.dart.
33
// Do not manually edit this file.
44

55
import 'package:instabug_flutter/utils/platform_manager.dart' as _i2;
66
import 'package:mockito/mockito.dart' as _i1;
77

88
// ignore_for_file: avoid_redundant_argument_values
9+
// ignore_for_file: avoid_setters_without_getters
910
// ignore_for_file: comment_references
11+
// ignore_for_file: implementation_imports
1012
// ignore_for_file: invalid_use_of_visible_for_testing_member
1113
// ignore_for_file: prefer_const_constructors
1214
// ignore_for_file: unnecessary_parenthesis
@@ -27,4 +29,6 @@ class MockPlatformManager extends _i1.Mock implements _i2.PlatformManager {
2729
bool isIOS() =>
2830
(super.noSuchMethod(Invocation.method(#isIOS, []), returnValue: false)
2931
as bool);
32+
@override
33+
String toString() => super.toString();
3034
}

0 commit comments

Comments
 (0)