8
8
#include " NetworkReporter.h"
9
9
10
10
#include < glog/logging.h>
11
+ #include < jsinspector-modern/cdp/CdpJson.h>
11
12
12
13
#include < stdexcept>
13
14
14
15
namespace facebook ::react::jsinspector_modern {
15
16
17
+ namespace {
18
+
19
+ /* *
20
+ * Get the CDP `ResourceType` for a given MIME type.
21
+ *
22
+ * https://chromedevtools.github.io/devtools-protocol/tot/Network/#type-ResourceType
23
+ */
24
+ std::string mimeTypeToResourceType (const std::string& mimeType) {
25
+ if (mimeType.find (" image/" ) == 0 ) {
26
+ return " Image" ;
27
+ }
28
+
29
+ if (mimeType.find (" video/" ) == 0 || mimeType.find (" audio/" ) == 0 ) {
30
+ return " Media" ;
31
+ }
32
+
33
+ if (mimeType == " application/javascript" || mimeType == " text/javascript" ||
34
+ mimeType == " application/x-javascript" ) {
35
+ return " Script" ;
36
+ }
37
+
38
+ if (mimeType == " application/json" || mimeType.find (" application/xml" ) == 0 ||
39
+ mimeType == " text/xml" ) {
40
+ // Assume XHR for JSON/XML types
41
+ return " XHR" ;
42
+ }
43
+
44
+ return " Other" ;
45
+ }
46
+
47
+ folly::dynamic headersToDynamic (const std::optional<Headers>& headers) {
48
+ folly::dynamic result = folly::dynamic::object;
49
+
50
+ if (headers) {
51
+ for (const auto & [key, value] : *headers) {
52
+ result[key] = value;
53
+ }
54
+ }
55
+
56
+ return result;
57
+ }
58
+
59
+ folly::dynamic requestToCdpParams (const RequestInfo& request) {
60
+ folly::dynamic result = folly::dynamic::object;
61
+ result[" url" ] = request.url ;
62
+ result[" method" ] = request.httpMethod ;
63
+ result[" headers" ] = headersToDynamic (request.headers );
64
+ result[" postData" ] = request.httpBody .value ();
65
+
66
+ return result;
67
+ }
68
+
69
+ folly::dynamic responseToCdpParams (
70
+ const ResponseInfo& response,
71
+ int encodedDataLength) {
72
+ auto headers = response.headers .value_or (Headers ());
73
+ std::string mimeType = " Other" ;
74
+
75
+ if (headers.find (" Content-Type" ) != headers.end ()) {
76
+ mimeType = mimeTypeToResourceType (headers.at (" Content-Type" ));
77
+ }
78
+
79
+ folly::dynamic result = folly::dynamic::object;
80
+ result[" url" ] = response.url ;
81
+ result[" status" ] = response.statusCode ;
82
+ result[" statusText" ] = " " ;
83
+ result[" headers" ] = headersToDynamic (response.headers );
84
+ result[" mimeType" ] = mimeType;
85
+ result[" encodedDataLength" ] = encodedDataLength;
86
+
87
+ return result;
88
+ }
89
+
90
+ /* *
91
+ * Get the current Unix timestamp in seconds (µs precision).
92
+ */
93
+ double getCurrentUnixTimestampSeconds () {
94
+ auto now = std::chrono::system_clock::now ().time_since_epoch ();
95
+ auto seconds = std::chrono::duration_cast<std::chrono::seconds>(now).count ();
96
+ auto micros =
97
+ std::chrono::duration_cast<std::chrono::microseconds>(now).count () %
98
+ 1000000 ;
99
+
100
+ return static_cast <double >(seconds) +
101
+ (static_cast <double >(micros) / 1000000.0 );
102
+ }
103
+
104
+ } // namespace
105
+
16
106
NetworkReporter& NetworkReporter::getInstance () {
17
107
static NetworkReporter tracer;
18
108
return tracer;
19
109
}
20
110
111
+ void NetworkReporter::setFrontendChannel (FrontendChannel frontendChannel) {
112
+ frontendChannel_ = std::move (frontendChannel);
113
+ }
114
+
21
115
bool NetworkReporter::enableDebugging () {
22
116
if (debuggingEnabled_.load (std::memory_order_acquire)) {
23
117
return false ;
@@ -38,13 +132,34 @@ bool NetworkReporter::disableDebugging() {
38
132
return true ;
39
133
}
40
134
41
- void NetworkReporter::reportRequestStart (const std::string& /* requestId*/ ) {
135
+ void NetworkReporter::reportRequestStart (
136
+ const std::string& requestId,
137
+ const RequestInfo& requestInfo,
138
+ int encodedDataLength,
139
+ const std::optional<ResponseInfo>& redirectResponse) {
42
140
if (!debuggingEnabled_.load (std::memory_order_relaxed)) {
43
141
return ;
44
142
}
45
143
46
- // TODO(T216933356)
47
- throw std::runtime_error (" Not implemented" );
144
+ double timestamp = getCurrentUnixTimestampSeconds ();
145
+
146
+ folly::dynamic params = folly::dynamic::object;
147
+ params[" requestId" ] = requestId;
148
+ params[" loaderId" ] = " " ;
149
+ params[" documentURL" ] = " mobile" ;
150
+ params[" request" ] = requestToCdpParams (requestInfo);
151
+ // NOTE: timestamp and wallTime share the same time unit and precision,
152
+ // except wallTime is from an arbitrary epoch - use the Unix epoch for both.
153
+ params[" timestamp" ] = timestamp;
154
+ params[" wallTime" ] = timestamp;
155
+ params[" initiator" ] = folly::dynamic::object (" type" , " script" );
156
+ params[" redirectHasExtraInfo" ] = redirectResponse.has_value ();
157
+ if (redirectResponse.has_value ()) {
158
+ params[" redirectResponse" ] =
159
+ responseToCdpParams (redirectResponse.value (), encodedDataLength);
160
+ }
161
+
162
+ frontendChannel_ (cdp::jsonNotification (" Network.requestWillBeSent" , params));
48
163
}
49
164
50
165
void NetworkReporter::reportConnectionTiming (const std::string& /* requestId*/ ) {
@@ -65,13 +180,26 @@ void NetworkReporter::reportRequestFailed(const std::string& /*requestId*/) {
65
180
throw std::runtime_error (" Not implemented" );
66
181
}
67
182
68
- void NetworkReporter::reportResponseStart (const std::string& /* requestId*/ ) {
183
+ void NetworkReporter::reportResponseStart (
184
+ const std::string& requestId,
185
+ const ResponseInfo& responseInfo,
186
+ int encodedDataLength) {
69
187
if (!debuggingEnabled_.load (std::memory_order_relaxed)) {
70
188
return ;
71
189
}
72
190
73
- // TODO(T216933356)
74
- throw std::runtime_error (" Not implemented" );
191
+ folly::dynamic responseParams =
192
+ responseToCdpParams (responseInfo, encodedDataLength);
193
+
194
+ folly::dynamic params = folly::dynamic::object;
195
+ params[" requestId" ] = requestId;
196
+ params[" loaderId" ] = " " ;
197
+ params[" timestamp" ] = getCurrentUnixTimestampSeconds ();
198
+ params[" type" ] = responseParams[" mimeType" ];
199
+ params[" response" ] = responseParams;
200
+ params[" hasExtraInfo" ] = false ;
201
+
202
+ frontendChannel_ (cdp::jsonNotification (" Network.responseReceived" , params));
75
203
}
76
204
77
205
void NetworkReporter::reportDataReceived (const std::string& /* requestId*/ ) {
@@ -83,13 +211,19 @@ void NetworkReporter::reportDataReceived(const std::string& /*requestId*/) {
83
211
throw std::runtime_error (" Not implemented" );
84
212
}
85
213
86
- void NetworkReporter::reportResponseEnd (const std::string& /* requestId*/ ) {
214
+ void NetworkReporter::reportResponseEnd (
215
+ const std::string& requestId,
216
+ int encodedDataLength) {
87
217
if (!debuggingEnabled_.load (std::memory_order_relaxed)) {
88
218
return ;
89
219
}
90
220
91
- // TODO(T216933356)
92
- throw std::runtime_error (" Not implemented" );
221
+ folly::dynamic params = folly::dynamic::object;
222
+ params[" requestId" ] = requestId;
223
+ params[" timestamp" ] = getCurrentUnixTimestampSeconds ();
224
+ params[" encodedDataLength" ] = encodedDataLength;
225
+
226
+ frontendChannel_ (cdp::jsonNotification (" Network.loadingFinished" , params));
93
227
}
94
228
95
229
} // namespace facebook::react::jsinspector_modern
0 commit comments