Skip to content

Commit 3d7102d

Browse files
committed
added mime checks, minor logic improvements in recording
1 parent 5a5c19c commit 3d7102d

File tree

4 files changed

+52
-7
lines changed

4 files changed

+52
-7
lines changed

packages/devtools_app/lib/src/screens/network/har_data_entry.dart

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,9 @@ class HarDataEntry {
122122
};
123123
}).toList();
124124

125+
final isBinary = !isTextMimeType(e.type);
126+
final responseBodyBytes = e.encodedResponse;
127+
125128
return <String, Object?>{
126129
NetworkEventKeys.startedDateTime.name:
127130
e.startTimestamp.toUtc().toIso8601String(),
@@ -155,8 +158,14 @@ class HarDataEntry {
155158
NetworkEventKeys.content.name: <String, Object?>{
156159
NetworkEventKeys.size.name: e.responseBody?.length,
157160
NetworkEventKeys.mimeType.name: e.type,
158-
NetworkEventKeys.text.name: e.responseBody,
161+
if (responseBodyBytes != null && isBinary) ...{
162+
NetworkEventKeys.text.name: base64.encode(responseBodyBytes),
163+
'encoding': 'base64',
164+
} else if (e.responseBody != null) ...{
165+
NetworkEventKeys.text.name: e.responseBody,
166+
},
159167
},
168+
160169
NetworkEventKeys.redirectURL.name: '',
161170
NetworkEventKeys.headersSize.name: calculateHeadersSize(
162171
e.responseHeaders,

packages/devtools_app/lib/src/screens/network/network_controller.dart

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,8 @@ class NetworkController extends DevToolsScreenController
7777
debugPrint('No valid request data to export');
7878
return '';
7979
}
80-
80+
// Build the HAR object
8181
try {
82-
// Build the HAR object
8382
final har = HarNetworkData(_httpRequests!);
8483
return ExportController().downloadFile(
8584
json.encode(har.toJson()),
@@ -205,8 +204,11 @@ class NetworkController extends DevToolsScreenController
205204
shouldLoad: (data) => !data.isEmpty,
206205
loadData: (data) => loadOfflineData(data),
207206
);
208-
}
209-
if (serviceConnection.serviceManager.connectedState.value.connected) {
207+
} else if (serviceConnection
208+
.serviceManager
209+
.connectedState
210+
.value
211+
.connected) {
210212
await startRecording();
211213
}
212214
}

packages/devtools_app/lib/src/shared/http/http_request_data.dart

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,27 @@ class DartIOHttpRequestData extends NetworkRequest {
102102
);
103103
_request = updated;
104104
final fullRequest = _request as HttpProfileRequest;
105-
_responseBody = utf8.decode(fullRequest.responseBody!);
106-
_requestBody = utf8.decode(fullRequest.requestBody!);
105+
final responseMime =
106+
responseHeaders?['content-type']?.toString().split(';').first;
107+
final requestMime =
108+
requestHeaders?['content-type']?.toString().split(';').first;
109+
110+
if (fullRequest.responseBody != null) {
111+
if (isTextMimeType(responseMime)) {
112+
_responseBody = utf8.decode(fullRequest.responseBody!);
113+
} else {
114+
_responseBody = base64.encode(fullRequest.responseBody!);
115+
}
116+
}
117+
118+
if (fullRequest.requestBody != null) {
119+
if (isTextMimeType(requestMime)) {
120+
_requestBody = utf8.decode(fullRequest.requestBody!);
121+
} else {
122+
_requestBody = base64.encode(fullRequest.requestBody!);
123+
}
124+
}
125+
107126
notifyListeners();
108127
}
109128
} finally {

packages/devtools_app/lib/src/shared/primitives/utils.dart

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1126,3 +1126,18 @@ String devtoolsAssetsBasePath({required String origin, required String path}) {
11261126
pathParts.removeLast();
11271127
return '$trimmedOrigin${pathParts.join(separator)}';
11281128
}
1129+
1130+
/// Returns `true` if the given [mimeType] is considered textual and can be
1131+
/// safely decoded as UTF-8 without base64 encoding.
1132+
///
1133+
/// This function is useful for determining whether the content of an HTTP
1134+
/// request or response can be directly included in a HAR or JSON file as
1135+
/// human-readable text.
1136+
bool isTextMimeType(String? mimeType) {
1137+
if (mimeType == null) return false;
1138+
return mimeType.startsWith('text/') ||
1139+
mimeType == 'application/json' ||
1140+
mimeType == 'application/javascript' ||
1141+
mimeType == 'application/xml' ||
1142+
mimeType == 'application/x-www-form-urlencoded';
1143+
}

0 commit comments

Comments
 (0)