react-native 0.83.0-nightly-20250907-02e3a999e → 0.83.0-nightly-20250909-e7ce4ff0b
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Libraries/AppDelegate/RCTAppDelegate.h +0 -2
- package/Libraries/AppDelegate/RCTAppDelegate.mm +1 -0
- package/Libraries/BatchedBridge/BatchedBridge.js +1 -0
- package/Libraries/BatchedBridge/MessageQueue.js +1 -0
- package/Libraries/Core/ReactNativeVersion.js +1 -1
- package/Libraries/Core/Timers/JSTimers.js +1 -0
- package/Libraries/Core/Timers/NativeTiming.js +1 -0
- package/Libraries/Core/Timers/immediateShim.js +1 -0
- package/Libraries/Network/RCTInspectorNetworkReporter.mm +2 -2
- package/Libraries/Renderer/shims/ReactNativeTypes.js +2 -1
- package/README.md +5 -2
- package/React/Base/RCTVersion.m +1 -1
- package/React/React-RCTFabric.podspec +1 -1
- package/ReactAndroid/gradle.properties +1 -1
- package/ReactAndroid/hermes-engine/build.gradle.kts +1 -1
- package/ReactAndroid/src/main/java/com/facebook/react/modules/systeminfo/ReactNativeVersion.kt +1 -1
- package/ReactAndroid/src/main/jni/CMakeLists.txt +3 -0
- package/ReactAndroid/src/main/jni/react/devsupport/CMakeLists.txt +1 -1
- package/ReactAndroid/src/main/jni/react/devsupport/JInspectorNetworkReporter.cpp +1 -1
- package/ReactAndroid/src/main/jni/react/hermes/reactexecutor/CMakeLists.txt +1 -1
- package/ReactAndroid/src/main/jni/react/runtime/hermes/jni/CMakeLists.txt +1 -1
- package/ReactAndroid/src/main/jni/react/runtime/jni/CMakeLists.txt +1 -1
- package/ReactCommon/cxxreact/ReactNativeVersion.h +1 -1
- package/ReactCommon/hermes/executor/CMakeLists.txt +1 -1
- package/ReactCommon/hermes/inspector-modern/CMakeLists.txt +1 -1
- package/ReactCommon/jsinspector-modern/NetworkIOAgent.cpp +8 -8
- package/ReactCommon/jsinspector-modern/network/CMakeLists.txt +1 -3
- package/ReactCommon/jsinspector-modern/network/CdpNetwork.cpp +7 -16
- package/ReactCommon/jsinspector-modern/network/CdpNetwork.h +5 -9
- package/ReactCommon/jsinspector-modern/network/HttpUtils.cpp +2 -1
- package/ReactCommon/jsinspector-modern/network/HttpUtils.h +3 -3
- package/ReactCommon/jsinspector-modern/network/NetworkHandler.cpp +209 -0
- package/ReactCommon/jsinspector-modern/network/NetworkHandler.h +147 -0
- package/ReactCommon/jsinspector-modern/network/React-jsinspectornetwork.podspec +0 -3
- package/ReactCommon/react/networking/CMakeLists.txt +21 -0
- package/ReactCommon/react/networking/NetworkReporter.cpp +192 -0
- package/ReactCommon/{jsinspector-modern/network → react/networking}/NetworkReporter.h +3 -62
- package/ReactCommon/{jsinspector-modern/network → react/networking}/NetworkTypes.h +2 -2
- package/ReactCommon/react/networking/React-networking.podspec +51 -0
- package/ReactCommon/react/runtime/CMakeLists.txt +1 -1
- package/ReactCommon/react/runtime/hermes/CMakeLists.txt +1 -1
- package/package.json +8 -8
- package/scripts/react_native_pods.rb +1 -0
- package/sdks/hermesc/osx-bin/hermes +0 -0
- package/sdks/hermesc/osx-bin/hermesc +0 -0
- package/sdks/hermesc/win64-bin/hermesc.exe +0 -0
- package/src/private/specs_DEPRECATED/modules/NativeTiming.js +1 -0
- package/types_generated/Libraries/Renderer/shims/ReactNativeTypes.d.ts +2 -1
- package/ReactCommon/jsinspector-modern/network/NetworkReporter.cpp +0 -316
|
@@ -29,7 +29,7 @@ export default class ReactNativeVersion {
|
|
|
29
29
|
static major: number = 0;
|
|
30
30
|
static minor: number = 83;
|
|
31
31
|
static patch: number = 0;
|
|
32
|
-
static prerelease: string | null = 'nightly-
|
|
32
|
+
static prerelease: string | null = 'nightly-20250909-e7ce4ff0b';
|
|
33
33
|
|
|
34
34
|
static getVersionString(): string {
|
|
35
35
|
return `${this.major}.${this.minor}.${this.patch}${this.prerelease != null ? `-${this.prerelease}` : ''}`;
|
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
#import "RCTNetworkConversions.h"
|
|
11
11
|
|
|
12
12
|
#import <React/RCTLog.h>
|
|
13
|
-
#import <
|
|
13
|
+
#import <react/networking/NetworkReporter.h>
|
|
14
14
|
|
|
15
|
-
using namespace facebook::react
|
|
15
|
+
using namespace facebook::react;
|
|
16
16
|
|
|
17
17
|
#ifdef REACT_NATIVE_DEBUGGER_ENABLED
|
|
18
18
|
namespace {
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* @noformat
|
|
8
8
|
* @nolint
|
|
9
9
|
* @flow strict
|
|
10
|
-
* @generated SignedSource<<
|
|
10
|
+
* @generated SignedSource<<c0e57723772ea5f1aa8c3c897ac3c216>>
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
13
|
import type {
|
|
@@ -135,6 +135,7 @@ export type RenderRootOptions = {
|
|
|
135
135
|
error: mixed,
|
|
136
136
|
errorInfo: {+componentStack?: ?string},
|
|
137
137
|
) => void,
|
|
138
|
+
onDefaultTransitionIndicator?: () => void | (() => void),
|
|
138
139
|
};
|
|
139
140
|
|
|
140
141
|
/**
|
package/README.md
CHANGED
|
@@ -17,10 +17,13 @@
|
|
|
17
17
|
<img src="https://img.shields.io/npm/v/react-native?color=brightgreen&label=npm%20package" alt="Current npm package version." />
|
|
18
18
|
</a>
|
|
19
19
|
<a href="https://reactnative.dev/docs/contributing">
|
|
20
|
-
<img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs welcome!" />
|
|
20
|
+
<img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg" alt="PRs are welcome!" />
|
|
21
21
|
</a>
|
|
22
22
|
<a href="https://twitter.com/intent/follow?screen_name=reactnative">
|
|
23
|
-
<img src="https://img.shields.io/twitter/follow/reactnative.svg?label=Follow%20@reactnative" alt="Follow @reactnative" />
|
|
23
|
+
<img src="https://img.shields.io/twitter/follow/reactnative.svg?label=Follow%20@reactnative" alt="Follow @reactnative on X" />
|
|
24
|
+
</a>
|
|
25
|
+
<a href="https://bsky.app/profile/reactnative.dev">
|
|
26
|
+
<img src="https://img.shields.io/badge/Bluesky-0285FF?logo=bluesky&logoColor=fff" alt="Follow @reactnative.dev on Bluesky" />
|
|
24
27
|
</a>
|
|
25
28
|
</p>
|
|
26
29
|
|
package/React/Base/RCTVersion.m
CHANGED
|
@@ -24,7 +24,7 @@ NSDictionary* RCTGetReactNativeVersion(void)
|
|
|
24
24
|
RCTVersionMajor: @(0),
|
|
25
25
|
RCTVersionMinor: @(83),
|
|
26
26
|
RCTVersionPatch: @(0),
|
|
27
|
-
RCTVersionPrerelease: @"nightly-
|
|
27
|
+
RCTVersionPrerelease: @"nightly-20250909-e7ce4ff0b",
|
|
28
28
|
};
|
|
29
29
|
});
|
|
30
30
|
return __rnVersion;
|
|
@@ -91,9 +91,9 @@ Pod::Spec.new do |s|
|
|
|
91
91
|
add_dependency(s, "React-RCTAnimation", :framework_name => 'RCTAnimation')
|
|
92
92
|
add_dependency(s, "React-jsinspector", :framework_name => 'jsinspector_modern')
|
|
93
93
|
add_dependency(s, "React-jsinspectorcdp", :framework_name => 'jsinspector_moderncdp')
|
|
94
|
-
add_dependency(s, "React-jsinspectornetwork", :framework_name => 'jsinspector_modernnetwork')
|
|
95
94
|
add_dependency(s, "React-jsinspectortracing", :framework_name => 'jsinspector_moderntracing')
|
|
96
95
|
add_dependency(s, "React-performancecdpmetrics", :framework_name => 'React_performancecdpmetrics')
|
|
96
|
+
add_dependency(s, "React-networking", :framework_name => 'React_networking')
|
|
97
97
|
add_dependency(s, "React-renderercss")
|
|
98
98
|
add_dependency(s, "React-RCTFBReactNativeSpec")
|
|
99
99
|
|
|
@@ -88,7 +88,7 @@ val hermesVersionProvider: Provider<String> =
|
|
|
88
88
|
val hermesVersionFile =
|
|
89
89
|
File(
|
|
90
90
|
reactNativeRootDir,
|
|
91
|
-
if (hermesV1Enabled) "sdks/.hermesv1version" else "
|
|
91
|
+
if (hermesV1Enabled) "sdks/.hermesv1version" else "sdks/.hermesversion",
|
|
92
92
|
)
|
|
93
93
|
|
|
94
94
|
if (hermesVersionFile.exists()) {
|
|
@@ -124,6 +124,7 @@ add_react_common_subdir(react/nativemodule/dom)
|
|
|
124
124
|
add_react_common_subdir(react/nativemodule/featureflags)
|
|
125
125
|
add_react_common_subdir(react/nativemodule/microtasks)
|
|
126
126
|
add_react_common_subdir(react/nativemodule/idlecallbacks)
|
|
127
|
+
add_react_common_subdir(react/networking)
|
|
127
128
|
add_react_common_subdir(jserrorhandler)
|
|
128
129
|
add_react_common_subdir(react/runtime)
|
|
129
130
|
add_react_common_subdir(react/runtime/hermes)
|
|
@@ -190,6 +191,7 @@ add_library(reactnative
|
|
|
190
191
|
$<TARGET_OBJECTS:react_nativemodule_featureflags>
|
|
191
192
|
$<TARGET_OBJECTS:react_nativemodule_idlecallbacks>
|
|
192
193
|
$<TARGET_OBJECTS:react_nativemodule_microtasks>
|
|
194
|
+
$<TARGET_OBJECTS:react_networking>
|
|
193
195
|
$<TARGET_OBJECTS:react_newarchdefaults>
|
|
194
196
|
$<TARGET_OBJECTS:react_performance_cdpmetrics>
|
|
195
197
|
$<TARGET_OBJECTS:react_performance_timeline>
|
|
@@ -279,6 +281,7 @@ target_include_directories(reactnative
|
|
|
279
281
|
$<TARGET_PROPERTY:react_nativemodule_featureflags,INTERFACE_INCLUDE_DIRECTORIES>
|
|
280
282
|
$<TARGET_PROPERTY:react_nativemodule_idlecallbacks,INTERFACE_INCLUDE_DIRECTORIES>
|
|
281
283
|
$<TARGET_PROPERTY:react_nativemodule_microtasks,INTERFACE_INCLUDE_DIRECTORIES>
|
|
284
|
+
$<TARGET_PROPERTY:react_networking,INTERFACE_INCLUDE_DIRECTORIES>
|
|
282
285
|
$<TARGET_PROPERTY:react_newarchdefaults,INTERFACE_INCLUDE_DIRECTORIES>
|
|
283
286
|
$<TARGET_PROPERTY:react_performance_cdpmetrics,INTERFACE_INCLUDE_DIRECTORIES>
|
|
284
287
|
$<TARGET_PROPERTY:react_performance_timeline,INTERFACE_INCLUDE_DIRECTORIES>
|
|
@@ -28,7 +28,7 @@ target_compile_reactnative_options(hermes_executor PRIVATE)
|
|
|
28
28
|
if(${CMAKE_BUILD_TYPE} MATCHES Debug OR REACT_NATIVE_DEBUG_OPTIMIZED)
|
|
29
29
|
target_compile_options(hermes_executor PRIVATE -DHERMES_ENABLE_DEBUGGER=1)
|
|
30
30
|
|
|
31
|
-
if (
|
|
31
|
+
if (HERMES_V1_ENABLED)
|
|
32
32
|
target_compile_options(hermes_executor PRIVATE -DHERMES_V1_ENABLED=1)
|
|
33
33
|
endif()
|
|
34
34
|
endif()
|
|
@@ -30,7 +30,7 @@ target_compile_reactnative_options(hermesinstancejni PRIVATE)
|
|
|
30
30
|
if(${CMAKE_BUILD_TYPE} MATCHES Debug OR REACT_NATIVE_DEBUG_OPTIMIZED)
|
|
31
31
|
target_compile_options(hermesinstancejni PRIVATE -DHERMES_ENABLE_DEBUGGER=1)
|
|
32
32
|
|
|
33
|
-
if (
|
|
33
|
+
if (HERMES_V1_ENABLED)
|
|
34
34
|
target_compile_options(hermesinstancejni PRIVATE -DHERMES_V1_ENABLED=1)
|
|
35
35
|
endif()
|
|
36
36
|
endif ()
|
|
@@ -20,7 +20,7 @@ target_compile_reactnative_options(rninstance PRIVATE)
|
|
|
20
20
|
if(${CMAKE_BUILD_TYPE} MATCHES Debug OR REACT_NATIVE_DEBUG_OPTIMIZED)
|
|
21
21
|
target_compile_options(rninstance PRIVATE -DHERMES_ENABLE_DEBUGGER=1)
|
|
22
22
|
|
|
23
|
-
if (
|
|
23
|
+
if (HERMES_V1_ENABLED)
|
|
24
24
|
target_compile_options(rninstance PRIVATE -DHERMES_V1_ENABLED=1)
|
|
25
25
|
endif()
|
|
26
26
|
endif ()
|
|
@@ -22,7 +22,7 @@ constexpr struct {
|
|
|
22
22
|
int32_t Major = 0;
|
|
23
23
|
int32_t Minor = 83;
|
|
24
24
|
int32_t Patch = 0;
|
|
25
|
-
std::string_view Prerelease = "nightly-
|
|
25
|
+
std::string_view Prerelease = "nightly-20250909-e7ce4ff0b";
|
|
26
26
|
} ReactNativeVersion;
|
|
27
27
|
|
|
28
28
|
} // namespace facebook::react
|
|
@@ -33,7 +33,7 @@ if(${CMAKE_BUILD_TYPE} MATCHES Debug OR REACT_NATIVE_DEBUG_OPTIMIZED)
|
|
|
33
33
|
-DHERMES_ENABLE_DEBUGGER=1
|
|
34
34
|
)
|
|
35
35
|
|
|
36
|
-
if (
|
|
36
|
+
if (HERMES_V1_ENABLED)
|
|
37
37
|
target_compile_options(hermes_executor_common PRIVATE -DHERMES_V1_ENABLED=1)
|
|
38
38
|
endif()
|
|
39
39
|
else()
|
|
@@ -24,7 +24,7 @@ if(${CMAKE_BUILD_TYPE} MATCHES Debug OR REACT_NATIVE_DEBUG_OPTIMIZED)
|
|
|
24
24
|
-DHERMES_ENABLE_DEBUGGER=1
|
|
25
25
|
)
|
|
26
26
|
|
|
27
|
-
if (
|
|
27
|
+
if (HERMES_V1_ENABLED)
|
|
28
28
|
target_compile_options(hermes_inspector_modern PRIVATE -DHERMES_V1_ENABLED=1)
|
|
29
29
|
endif()
|
|
30
30
|
endif()
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
#include "Base64.h"
|
|
12
12
|
#include "Utf8.h"
|
|
13
13
|
|
|
14
|
-
#include <jsinspector-modern/network/
|
|
14
|
+
#include <jsinspector-modern/network/NetworkHandler.h>
|
|
15
15
|
|
|
16
16
|
#include <sstream>
|
|
17
17
|
#include <tuple>
|
|
@@ -272,19 +272,19 @@ bool NetworkIOAgent::handleRequest(
|
|
|
272
272
|
}
|
|
273
273
|
|
|
274
274
|
if (InspectorFlags::getInstance().getNetworkInspectionEnabled()) {
|
|
275
|
-
auto&
|
|
275
|
+
auto& networkHandler = NetworkHandler::getInstance();
|
|
276
276
|
|
|
277
277
|
// @cdp Network.enable support is experimental.
|
|
278
278
|
if (req.method == "Network.enable") {
|
|
279
|
-
|
|
280
|
-
|
|
279
|
+
networkHandler.setFrontendChannel(frontendChannel_);
|
|
280
|
+
networkHandler.enable();
|
|
281
281
|
frontendChannel_(cdp::jsonResult(req.id));
|
|
282
282
|
return true;
|
|
283
283
|
}
|
|
284
284
|
|
|
285
285
|
// @cdp Network.disable support is experimental.
|
|
286
286
|
if (req.method == "Network.disable") {
|
|
287
|
-
|
|
287
|
+
networkHandler.disable();
|
|
288
288
|
frontendChannel_(cdp::jsonResult(req.id));
|
|
289
289
|
return true;
|
|
290
290
|
}
|
|
@@ -497,9 +497,9 @@ void NetworkIOAgent::handleGetResponseBody(const cdp::PreparsedRequest& req) {
|
|
|
497
497
|
return;
|
|
498
498
|
}
|
|
499
499
|
|
|
500
|
-
auto&
|
|
500
|
+
auto& networkHandler = NetworkHandler::getInstance();
|
|
501
501
|
|
|
502
|
-
if (!
|
|
502
|
+
if (!networkHandler.isEnabled()) {
|
|
503
503
|
frontendChannel_(cdp::jsonError(
|
|
504
504
|
requestId,
|
|
505
505
|
cdp::ErrorCode::InvalidRequest,
|
|
@@ -508,7 +508,7 @@ void NetworkIOAgent::handleGetResponseBody(const cdp::PreparsedRequest& req) {
|
|
|
508
508
|
}
|
|
509
509
|
|
|
510
510
|
auto storedResponse =
|
|
511
|
-
|
|
511
|
+
networkHandler.getResponseBody(req.params.at("requestId").asString());
|
|
512
512
|
|
|
513
513
|
if (!storedResponse) {
|
|
514
514
|
frontendChannel_(cdp::jsonError(
|
|
@@ -27,15 +27,6 @@ folly::dynamic headersToDynamic(const std::optional<Headers>& headers) {
|
|
|
27
27
|
|
|
28
28
|
} // namespace
|
|
29
29
|
|
|
30
|
-
/* static */ Request Request::fromInputParams(const RequestInfo& requestInfo) {
|
|
31
|
-
return {
|
|
32
|
-
.url = requestInfo.url,
|
|
33
|
-
.method = requestInfo.httpMethod,
|
|
34
|
-
.headers = requestInfo.headers,
|
|
35
|
-
.postData = requestInfo.httpBody,
|
|
36
|
-
};
|
|
37
|
-
}
|
|
38
|
-
|
|
39
30
|
folly::dynamic Request::toDynamic() const {
|
|
40
31
|
folly::dynamic result = folly::dynamic::object;
|
|
41
32
|
|
|
@@ -48,16 +39,16 @@ folly::dynamic Request::toDynamic() const {
|
|
|
48
39
|
}
|
|
49
40
|
|
|
50
41
|
/* static */ Response Response::fromInputParams(
|
|
51
|
-
const
|
|
42
|
+
const std::string& url,
|
|
43
|
+
uint16_t status,
|
|
44
|
+
const std::optional<Headers>& headers,
|
|
52
45
|
int encodedDataLength) {
|
|
53
|
-
auto headers = responseInfo.headers.value_or(Headers());
|
|
54
|
-
|
|
55
46
|
return {
|
|
56
|
-
.url =
|
|
57
|
-
.status =
|
|
58
|
-
.statusText = httpReasonPhrase(
|
|
47
|
+
.url = url,
|
|
48
|
+
.status = status,
|
|
49
|
+
.statusText = httpReasonPhrase(status),
|
|
59
50
|
.headers = headers,
|
|
60
|
-
.mimeType = mimeTypeFromHeaders(headers),
|
|
51
|
+
.mimeType = mimeTypeFromHeaders(headers.value_or(Headers())),
|
|
61
52
|
.encodedDataLength = encodedDataLength,
|
|
62
53
|
};
|
|
63
54
|
}
|
|
@@ -7,8 +7,6 @@
|
|
|
7
7
|
|
|
8
8
|
#pragma once
|
|
9
9
|
|
|
10
|
-
#include "NetworkTypes.h"
|
|
11
|
-
|
|
12
10
|
#include <folly/dynamic.h>
|
|
13
11
|
|
|
14
12
|
#include <string>
|
|
@@ -18,6 +16,8 @@
|
|
|
18
16
|
|
|
19
17
|
namespace facebook::react::jsinspector_modern::cdp::network {
|
|
20
18
|
|
|
19
|
+
using Headers = std::map<std::string, std::string>;
|
|
20
|
+
|
|
21
21
|
/**
|
|
22
22
|
* https://chromedevtools.github.io/devtools-protocol/tot/Network/#type-Request
|
|
23
23
|
*/
|
|
@@ -27,12 +27,6 @@ struct Request {
|
|
|
27
27
|
std::optional<Headers> headers;
|
|
28
28
|
std::optional<std::string> postData;
|
|
29
29
|
|
|
30
|
-
/**
|
|
31
|
-
* Convenience function to construct a `Request` from the generic
|
|
32
|
-
* `RequestInfo` input object.
|
|
33
|
-
*/
|
|
34
|
-
static Request fromInputParams(const RequestInfo& requestInfo);
|
|
35
|
-
|
|
36
30
|
folly::dynamic toDynamic() const;
|
|
37
31
|
};
|
|
38
32
|
|
|
@@ -52,7 +46,9 @@ struct Response {
|
|
|
52
46
|
* `ResponseInfo` input object.
|
|
53
47
|
*/
|
|
54
48
|
static Response fromInputParams(
|
|
55
|
-
const
|
|
49
|
+
const std::string& url,
|
|
50
|
+
uint16_t status,
|
|
51
|
+
const std::optional<Headers>& headers,
|
|
56
52
|
int encodedDataLength);
|
|
57
53
|
|
|
58
54
|
folly::dynamic toDynamic() const;
|
|
@@ -146,7 +146,8 @@ std::string httpReasonPhrase(uint16_t status) {
|
|
|
146
146
|
return "<Unknown>";
|
|
147
147
|
}
|
|
148
148
|
|
|
149
|
-
std::string mimeTypeFromHeaders(
|
|
149
|
+
std::string mimeTypeFromHeaders(
|
|
150
|
+
const std::map<std::string, std::string>& headers) {
|
|
150
151
|
std::string mimeType = "application/octet-stream";
|
|
151
152
|
|
|
152
153
|
for (const auto& [name, value] : headers) {
|
|
@@ -7,8 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
#pragma once
|
|
9
9
|
|
|
10
|
-
#include
|
|
11
|
-
|
|
10
|
+
#include <map>
|
|
12
11
|
#include <string>
|
|
13
12
|
|
|
14
13
|
namespace facebook::react::jsinspector_modern {
|
|
@@ -22,6 +21,7 @@ std::string httpReasonPhrase(uint16_t status);
|
|
|
22
21
|
* Get the MIME type for a response based on the 'Content-Type' header. If
|
|
23
22
|
* the header is not present, returns 'application/octet-stream'.
|
|
24
23
|
*/
|
|
25
|
-
std::string mimeTypeFromHeaders(
|
|
24
|
+
std::string mimeTypeFromHeaders(
|
|
25
|
+
const std::map<std::string, std::string>& headers);
|
|
26
26
|
|
|
27
27
|
} // namespace facebook::react::jsinspector_modern
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the MIT license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
#include "NetworkHandler.h"
|
|
9
|
+
|
|
10
|
+
#include <jsinspector-modern/cdp/CdpJson.h>
|
|
11
|
+
|
|
12
|
+
#include <glog/logging.h>
|
|
13
|
+
#include <chrono>
|
|
14
|
+
|
|
15
|
+
namespace facebook::react::jsinspector_modern {
|
|
16
|
+
|
|
17
|
+
namespace {
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Get the current Unix timestamp in seconds (µs precision, CDP format).
|
|
21
|
+
*/
|
|
22
|
+
double getCurrentUnixTimestampSeconds() {
|
|
23
|
+
auto now = std::chrono::system_clock::now().time_since_epoch();
|
|
24
|
+
auto seconds = std::chrono::duration_cast<std::chrono::seconds>(now).count();
|
|
25
|
+
auto micros =
|
|
26
|
+
std::chrono::duration_cast<std::chrono::microseconds>(now).count() %
|
|
27
|
+
1000000;
|
|
28
|
+
|
|
29
|
+
return static_cast<double>(seconds) +
|
|
30
|
+
(static_cast<double>(micros) / 1000000.0);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
} // namespace
|
|
34
|
+
|
|
35
|
+
NetworkHandler& NetworkHandler::getInstance() {
|
|
36
|
+
static NetworkHandler instance;
|
|
37
|
+
return instance;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
void NetworkHandler::setFrontendChannel(FrontendChannel frontendChannel) {
|
|
41
|
+
frontendChannel_ = std::move(frontendChannel);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
bool NetworkHandler::enable() {
|
|
45
|
+
if (enabled_.load(std::memory_order_acquire)) {
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
enabled_.store(true, std::memory_order_release);
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
bool NetworkHandler::disable() {
|
|
54
|
+
if (!enabled_.load(std::memory_order_acquire)) {
|
|
55
|
+
return false;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
enabled_.store(false, std::memory_order_release);
|
|
59
|
+
requestBodyBuffer_.clear();
|
|
60
|
+
return true;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
void NetworkHandler::onRequestWillBeSent(
|
|
64
|
+
const std::string& requestId,
|
|
65
|
+
const cdp::network::Request& request,
|
|
66
|
+
const std::optional<cdp::network::Response>& redirectResponse) {
|
|
67
|
+
if (!isEnabledNoSync()) {
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
double timestamp = getCurrentUnixTimestampSeconds();
|
|
72
|
+
auto params = cdp::network::RequestWillBeSentParams{
|
|
73
|
+
.requestId = requestId,
|
|
74
|
+
.loaderId = "",
|
|
75
|
+
.documentURL = "mobile",
|
|
76
|
+
.request = request,
|
|
77
|
+
// NOTE: Both timestamp and wallTime use the same unit, however wallTime
|
|
78
|
+
// is relative to an "arbitrary epoch". In our implementation, use the
|
|
79
|
+
// Unix epoch for both.
|
|
80
|
+
.timestamp = timestamp,
|
|
81
|
+
.wallTime = timestamp,
|
|
82
|
+
.initiator = folly::dynamic::object("type", "script"),
|
|
83
|
+
.redirectHasExtraInfo = redirectResponse.has_value(),
|
|
84
|
+
.redirectResponse = redirectResponse,
|
|
85
|
+
};
|
|
86
|
+
|
|
87
|
+
frontendChannel_(
|
|
88
|
+
cdp::jsonNotification("Network.requestWillBeSent", params.toDynamic()));
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
void NetworkHandler::onRequestWillBeSentExtraInfo(
|
|
92
|
+
const std::string& requestId,
|
|
93
|
+
const Headers& headers) {
|
|
94
|
+
if (!isEnabledNoSync()) {
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
auto params = cdp::network::RequestWillBeSentExtraInfoParams{
|
|
99
|
+
.requestId = requestId,
|
|
100
|
+
.headers = headers,
|
|
101
|
+
.connectTiming = {.requestTime = getCurrentUnixTimestampSeconds()},
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
frontendChannel_(cdp::jsonNotification(
|
|
105
|
+
"Network.requestWillBeSentExtraInfo", params.toDynamic()));
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
void NetworkHandler::onResponseReceived(
|
|
109
|
+
const std::string& requestId,
|
|
110
|
+
const cdp::network::Response& response) {
|
|
111
|
+
if (!isEnabledNoSync()) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
auto resourceType = cdp::network::resourceTypeFromMimeType(response.mimeType);
|
|
116
|
+
resourceTypeMap_.emplace(requestId, resourceType);
|
|
117
|
+
|
|
118
|
+
auto params = cdp::network::ResponseReceivedParams{
|
|
119
|
+
.requestId = requestId,
|
|
120
|
+
.loaderId = "",
|
|
121
|
+
.timestamp = getCurrentUnixTimestampSeconds(),
|
|
122
|
+
.type = resourceType,
|
|
123
|
+
.response = response,
|
|
124
|
+
.hasExtraInfo = false,
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
frontendChannel_(
|
|
128
|
+
cdp::jsonNotification("Network.responseReceived", params.toDynamic()));
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
void NetworkHandler::onDataReceived(
|
|
132
|
+
const std::string& requestId,
|
|
133
|
+
int dataLength,
|
|
134
|
+
int encodedDataLength) {
|
|
135
|
+
if (!isEnabledNoSync()) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
auto params = cdp::network::DataReceivedParams{
|
|
140
|
+
.requestId = requestId,
|
|
141
|
+
.timestamp = getCurrentUnixTimestampSeconds(),
|
|
142
|
+
.dataLength = dataLength,
|
|
143
|
+
.encodedDataLength = encodedDataLength,
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
frontendChannel_(
|
|
147
|
+
cdp::jsonNotification("Network.dataReceived", params.toDynamic()));
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
void NetworkHandler::onLoadingFinished(
|
|
151
|
+
const std::string& requestId,
|
|
152
|
+
int encodedDataLength) {
|
|
153
|
+
if (!isEnabledNoSync()) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
auto params = cdp::network::LoadingFinishedParams{
|
|
158
|
+
.requestId = requestId,
|
|
159
|
+
.timestamp = getCurrentUnixTimestampSeconds(),
|
|
160
|
+
.encodedDataLength = encodedDataLength,
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
frontendChannel_(
|
|
164
|
+
cdp::jsonNotification("Network.loadingFinished", params.toDynamic()));
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
void NetworkHandler::onLoadingFailed(
|
|
168
|
+
const std::string& requestId,
|
|
169
|
+
bool cancelled) const {
|
|
170
|
+
if (!isEnabledNoSync()) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
auto params = cdp::network::LoadingFailedParams{
|
|
175
|
+
.requestId = requestId,
|
|
176
|
+
.timestamp = getCurrentUnixTimestampSeconds(),
|
|
177
|
+
.type = resourceTypeMap_.find(requestId) != resourceTypeMap_.end()
|
|
178
|
+
? resourceTypeMap_.at(requestId)
|
|
179
|
+
: "Other",
|
|
180
|
+
.errorText = cancelled ? "net::ERR_ABORTED" : "net::ERR_FAILED",
|
|
181
|
+
.canceled = cancelled,
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
frontendChannel_(
|
|
185
|
+
cdp::jsonNotification("Network.loadingFailed", params.toDynamic()));
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
void NetworkHandler::storeResponseBody(
|
|
189
|
+
const std::string& requestId,
|
|
190
|
+
std::string_view body,
|
|
191
|
+
bool base64Encoded) {
|
|
192
|
+
std::lock_guard<std::mutex> lock(requestBodyMutex_);
|
|
193
|
+
requestBodyBuffer_.put(requestId, body, base64Encoded);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
std::optional<std::tuple<std::string, bool>> NetworkHandler::getResponseBody(
|
|
197
|
+
const std::string& requestId) {
|
|
198
|
+
std::lock_guard<std::mutex> lock(requestBodyMutex_);
|
|
199
|
+
auto responseBody = requestBodyBuffer_.get(requestId);
|
|
200
|
+
|
|
201
|
+
if (responseBody == nullptr) {
|
|
202
|
+
return std::nullopt;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
return std::make_optional<std::tuple<std::string, bool>>(
|
|
206
|
+
responseBody->data, responseBody->base64Encoded);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
} // namespace facebook::react::jsinspector_modern
|