/
githubmr
/
facebook-react-native
Обзор
Документация
Войти
/
githubmr
/
facebook-react-native
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
main
packages/react-native/ReactCommon/react/networking/NetworkReporter.cpp
251 строка
8 KB
Alex Hunt
Improve Network trace event field coverage (#53840)
19 сен 2025, 00:41
19 сен 2025, 00:41
cb7453f
Код
Авторство
О чём код?
/* * Copyright (c) Meta Platforms, Inc. and affiliates. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. */ #include "NetworkReporter.h" #ifdef REACT_NATIVE_DEBUGGER_ENABLED #include <jsinspector-modern/network/CdpNetwork.h> #include <jsinspector-modern/network/NetworkHandler.h> #include <jsinspector-modern/tracing/PerformanceTracer.h> #endif #include <jsinspector-modern/network/HttpUtils.h> #include <react/featureflags/ReactNativeFeatureFlags.h> #include <react/performance/timeline/PerformanceEntryReporter.h> namespace facebook::react { NetworkReporter& NetworkReporter::getInstance() { static NetworkReporter instance; return instance; } bool NetworkReporter::isDebuggingEnabled() const { #ifdef REACT_NATIVE_DEBUGGER_ENABLED return jsinspector_modern::NetworkHandler::getInstance().isEnabled(); #else return false; #endif } void NetworkReporter::reportRequestStart( const std::string& requestId, const RequestInfo& requestInfo, int encodedDataLength, const std::optional<ResponseInfo>& redirectResponse) { auto now = HighResTimeStamp::now(); // All builds: Annotate PerformanceResourceTiming metadata { std::lock_guard<std::mutex> lock(perfTimingsMutex_); perfTimingsBuffer_.emplace( requestId, ResourceTimingData{ .url = requestInfo.url, .fetchStart = now, .requestStart = now, }); } #ifdef REACT_NATIVE_DEBUGGER_ENABLED auto headers = requestInfo.headers.value_or(Headers{}); // Debugger enabled: CDP event handling jsinspector_modern::NetworkHandler::getInstance().onRequestWillBeSent( requestId, { .url = requestInfo.url, .method = requestInfo.httpMethod, .headers = headers, .postData = requestInfo.httpBody, }, redirectResponse.has_value() ? std::optional<jsinspector_modern::cdp::network::Response>( jsinspector_modern::cdp::network::Response::fromInputParams( redirectResponse->url, redirectResponse->statusCode, redirectResponse->headers.value_or(Headers{}), encodedDataLength)) : std::nullopt); // Debugger enabled: Add trace events to Performance timeline auto& performanceTracer = jsinspector_modern::tracing::PerformanceTracer::getInstance(); performanceTracer.reportResourceSendRequest( requestId, now, requestInfo.url, requestInfo.httpMethod, headers); #endif } void NetworkReporter::reportConnectionTiming( const std::string& requestId, const std::optional<Headers>& headers) { auto now = HighResTimeStamp::now(); // All builds: Annotate PerformanceResourceTiming metadata { std::lock_guard<std::mutex> lock(perfTimingsMutex_); auto it = perfTimingsBuffer_.find(requestId); if (it != perfTimingsBuffer_.end()) { it->second.connectStart = now; } } #ifdef REACT_NATIVE_DEBUGGER_ENABLED // Debugger enabled: CDP event handling jsinspector_modern::NetworkHandler::getInstance() .onRequestWillBeSentExtraInfo(requestId, headers.value_or(Headers{})); #endif } void NetworkReporter::reportResponseStart( const std::string& requestId, const ResponseInfo& responseInfo, int encodedDataLength) { auto now = HighResTimeStamp::now(); auto headers = responseInfo.headers.value_or(Headers{}); // All builds: Annotate PerformanceResourceTiming metadata { std::lock_guard<std::mutex> lock(perfTimingsMutex_); auto it = perfTimingsBuffer_.find(requestId); if (it != perfTimingsBuffer_.end()) { auto contentType = jsinspector_modern::mimeTypeFromHeaders(headers); it->second.connectEnd = now; it->second.responseStart = now; it->second.responseStatus = responseInfo.statusCode; it->second.contentType = contentType; it->second.encodedBodySize = encodedDataLength; it->second.decodedBodySize = encodedDataLength; } } #ifdef REACT_NATIVE_DEBUGGER_ENABLED // Debugger enabled: CDP event handling jsinspector_modern::NetworkHandler::getInstance().onResponseReceived( requestId, jsinspector_modern::cdp::network::Response::fromInputParams( responseInfo.url, responseInfo.statusCode, headers, encodedDataLength)); // Debugger enabled: Add trace event to Performance timeline { folly::dynamic timingData = folly::dynamic::object(); std::lock_guard<std::mutex> lock(perfTimingsMutex_); auto it = perfTimingsBuffer_.find(requestId); if (it != perfTimingsBuffer_.end()) { // TODO(T238364329): All relative values in timingData should be based on // fetchStart, once implemented. auto requestStart = it->second.requestStart; timingData["requestTime"] = requestStart.toDOMHighResTimeStamp() / 1000; timingData["sendStart"] = 0; timingData["sendEnd"] = (*it->second.connectStart - requestStart).toDOMHighResTimeStamp(); timingData["receiveHeadersStart"] = (*it->second.connectStart - requestStart).toDOMHighResTimeStamp(); timingData["receiveHeadersEnd"] = (now - requestStart).toDOMHighResTimeStamp(); } jsinspector_modern::tracing::PerformanceTracer::getInstance() .reportResourceReceiveResponse( requestId, now, responseInfo.statusCode, headers, encodedDataLength, std::move(timingData)); } #endif } void NetworkReporter::reportDataReceived( const std::string& requestId, int dataLength, const std::optional<int>& encodedDataLength) { #ifdef REACT_NATIVE_DEBUGGER_ENABLED // Debugger enabled: CDP event handling jsinspector_modern::NetworkHandler::getInstance().onDataReceived( requestId, dataLength, encodedDataLength.value_or(dataLength)); #endif } void NetworkReporter::reportResponseEnd( const std::string& requestId, int encodedDataLength) { auto now = HighResTimeStamp::now(); if (ReactNativeFeatureFlags::enableResourceTimingAPI()) { // All builds: Report PerformanceResourceTiming event { std::lock_guard<std::mutex> lock(perfTimingsMutex_); auto it = perfTimingsBuffer_.find(requestId); if (it != perfTimingsBuffer_.end()) { auto& eventData = it->second; PerformanceEntryReporter::getInstance()->reportResourceTiming( eventData.url, eventData.fetchStart, eventData.requestStart, eventData.connectStart.value_or(now), eventData.connectEnd.value_or(now), eventData.responseStart.value_or(now), now, eventData.responseStatus, eventData.contentType, eventData.encodedBodySize, eventData.decodedBodySize); perfTimingsBuffer_.erase(requestId); } } } #ifdef REACT_NATIVE_DEBUGGER_ENABLED // Debugger enabled: CDP event handling jsinspector_modern::NetworkHandler::getInstance().onLoadingFinished( requestId, encodedDataLength); // Debugger enabled: Add trace event to Performance timeline { int decodedBodyLength = 0; std::lock_guard<std::mutex> lock(perfTimingsMutex_); auto it = perfTimingsBuffer_.find(requestId); if (it != perfTimingsBuffer_.end() && it->second.contentType.starts_with("image/")) { decodedBodyLength = it->second.decodedBodySize; } jsinspector_modern::tracing::PerformanceTracer::getInstance() .reportResourceFinish( requestId, now, encodedDataLength, decodedBodyLength); } #endif } void NetworkReporter::reportRequestFailed( const std::string& requestId, bool cancelled) const { #ifdef REACT_NATIVE_DEBUGGER_ENABLED // Debugger enabled: CDP event handling jsinspector_modern::NetworkHandler::getInstance().onLoadingFailed( requestId, cancelled); #endif } void NetworkReporter::storeResponseBody( const std::string& requestId, std::string_view body, bool base64Encoded) { #ifdef REACT_NATIVE_DEBUGGER_ENABLED // Debugger enabled: Store fetched response body for later CDP retrieval jsinspector_modern::NetworkHandler::getInstance().storeResponseBody( requestId, body, base64Encoded); #endif } } // namespace facebook::react