-
Notifications
You must be signed in to change notification settings - Fork 353
/
http_client_request_profile.dart
118 lines (104 loc) · 3.83 KB
/
http_client_request_profile.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
part of 'http_profile.dart';
/// Describes an event related to an HTTP request.
final class HttpProfileRequestEvent {
final int _timestamp;
final String _name;
HttpProfileRequestEvent({required DateTime timestamp, required String name})
: _timestamp = timestamp.microsecondsSinceEpoch,
_name = name;
Map<String, dynamic> _toJson() => <String, dynamic>{
'timestamp': _timestamp,
'event': _name,
};
}
/// A record of debugging information about an HTTP request.
final class HttpClientRequestProfile {
/// Whether HTTP profiling is enabled or not.
///
/// The value can be changed programmatically or through the DevTools Network
/// UX.
static bool get profilingEnabled => HttpClient.enableTimelineLogging;
static set profilingEnabled(bool enabled) =>
HttpClient.enableTimelineLogging = enabled;
final _data = <String, dynamic>{};
/// Records an event related to the request.
///
/// Usage example:
///
/// ```dart
/// profile.addEvent(
/// HttpProfileRequestEvent(
/// timestamp: DateTime.now(),
/// name: "Connection Established",
/// ),
/// );
/// profile.addEvent(
/// HttpProfileRequestEvent(
/// timestamp: DateTime.now(),
/// name: "Remote Disconnected",
/// ),
/// );
/// ```
void addEvent(HttpProfileRequestEvent event) {
(_data['events'] as List<Map<String, dynamic>>).add(event._toJson());
_updated();
}
/// Details about the request.
late final HttpProfileRequestData requestData;
/// Details about the response.
late final HttpProfileResponseData responseData;
void _updated() =>
_data['_lastUpdateTime'] = DateTime.now().microsecondsSinceEpoch;
HttpClientRequestProfile._({
required DateTime requestStartTime,
required String requestMethod,
required String requestUri,
}) {
_data['isolateId'] = Service.getIsolateId(Isolate.current)!;
_data['requestStartTimestamp'] = requestStartTime.microsecondsSinceEpoch;
_data['requestMethod'] = requestMethod;
_data['requestUri'] = requestUri;
_data['events'] = <Map<String, dynamic>>[];
_data['requestData'] = <String, dynamic>{};
requestData = HttpProfileRequestData._(_data, _updated);
_data['responseData'] = <String, dynamic>{};
responseData = HttpProfileResponseData._(_data, _updated);
_data['requestBodyBytes'] = <int>[];
requestData._body.stream.listen(
(final bytes) => (_data['requestBodyBytes'] as List<int>).addAll(bytes),
);
_data['responseBodyBytes'] = <int>[];
responseData._body.stream.listen(
(final bytes) => (_data['responseBodyBytes'] as List<int>).addAll(bytes),
);
// This entry is needed to support the updatedSince parameter of
// ext.dart.io.getHttpProfile.
_updated();
}
/// If HTTP profiling is enabled, returns an [HttpClientRequestProfile],
/// otherwise returns `null`.
static HttpClientRequestProfile? profile({
/// The time at which the request was initiated.
required DateTime requestStartTime,
/// The HTTP request method associated with the request.
required String requestMethod,
/// The URI to which the request was sent.
required String requestUri,
}) {
// Always return `null` in product mode so that the profiling code can be
// tree shaken away.
if (const bool.fromEnvironment('dart.vm.product') || !profilingEnabled) {
return null;
}
final requestProfile = HttpClientRequestProfile._(
requestStartTime: requestStartTime,
requestMethod: requestMethod,
requestUri: requestUri,
);
addHttpClientProfilingData(requestProfile._data);
return requestProfile;
}
}