@npaw/forge-react-native 10.0.1 → 10.0.4
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/android/build.gradle +1 -1
- package/ios/ForgeApple/ForgeKernelFFI.xcframework/Info.plist +8 -8
- package/ios/ForgeApple/ForgeKernelFFI.xcframework/ios-arm64/libForgeKernelFFI.a +0 -0
- package/ios/ForgeApple/ForgeKernelFFI.xcframework/ios-arm64_x86_64-simulator/libForgeKernelFFI.a +0 -0
- package/ios/ForgeApple/ForgeKernelFFI.xcframework/tvos-arm64/libForgeKernelFFI.a +0 -0
- package/ios/ForgeApple/ForgeKernelFFI.xcframework/tvos-arm64-simulator/libForgeKernelFFI.a +0 -0
- package/ios/ForgeApple/Sources/ForgeKernelUniFFI/forge_kernel.swift +58 -2
- package/ios/ForgeApple/Sources/NPAWForgeCore/DeviceInsightsCollector.swift +33 -7
- package/ios/ForgeApple/Sources/NPAWForgeCore/ForgeRuntime.swift +2 -2
- package/ios/ForgeApple/Sources/NPAWForgeCore/NPAWForge.swift +1 -1
- package/ios/ForgeApple/Sources/NPAWForgeCore/NativeUniFFIRuntime.swift +5 -1
- package/ios/ForgeApple/Sources/NPAWForgeCore/NetworkRequestRecord.swift +22 -1
- package/ios/ForgeApple/Sources/NPAWForgeNetworkCaptureObjC/NPAWForgeNetworkSwizzler.m +17 -0
- package/package.json +1 -1
package/android/build.gradle
CHANGED
|
@@ -28,7 +28,7 @@ def safeExtGet(prop, fallback) {
|
|
|
28
28
|
// FORGE_CORE_VERSION (see scripts/react-native/hydrate-natives.sh).
|
|
29
29
|
def forgeCoreVersion = project.hasProperty('NpawForge_forgeCoreVersion')
|
|
30
30
|
? project.property('NpawForge_forgeCoreVersion')
|
|
31
|
-
: (System.getenv('FORGE_CORE_VERSION') ?: '10.0.
|
|
31
|
+
: (System.getenv('FORGE_CORE_VERSION') ?: '10.0.4')
|
|
32
32
|
|
|
33
33
|
android {
|
|
34
34
|
namespace 'com.npaw.forge.reactnative'
|
|
@@ -10,15 +10,18 @@
|
|
|
10
10
|
<key>HeadersPath</key>
|
|
11
11
|
<string>Headers</string>
|
|
12
12
|
<key>LibraryIdentifier</key>
|
|
13
|
-
<string>ios-
|
|
13
|
+
<string>ios-arm64_x86_64-simulator</string>
|
|
14
14
|
<key>LibraryPath</key>
|
|
15
15
|
<string>libForgeKernelFFI.a</string>
|
|
16
16
|
<key>SupportedArchitectures</key>
|
|
17
17
|
<array>
|
|
18
18
|
<string>arm64</string>
|
|
19
|
+
<string>x86_64</string>
|
|
19
20
|
</array>
|
|
20
21
|
<key>SupportedPlatform</key>
|
|
21
22
|
<string>ios</string>
|
|
23
|
+
<key>SupportedPlatformVariant</key>
|
|
24
|
+
<string>simulator</string>
|
|
22
25
|
</dict>
|
|
23
26
|
<dict>
|
|
24
27
|
<key>BinaryPath</key>
|
|
@@ -26,7 +29,7 @@
|
|
|
26
29
|
<key>HeadersPath</key>
|
|
27
30
|
<string>Headers</string>
|
|
28
31
|
<key>LibraryIdentifier</key>
|
|
29
|
-
<string>
|
|
32
|
+
<string>ios-arm64</string>
|
|
30
33
|
<key>LibraryPath</key>
|
|
31
34
|
<string>libForgeKernelFFI.a</string>
|
|
32
35
|
<key>SupportedArchitectures</key>
|
|
@@ -34,7 +37,7 @@
|
|
|
34
37
|
<string>arm64</string>
|
|
35
38
|
</array>
|
|
36
39
|
<key>SupportedPlatform</key>
|
|
37
|
-
<string>
|
|
40
|
+
<string>ios</string>
|
|
38
41
|
</dict>
|
|
39
42
|
<dict>
|
|
40
43
|
<key>BinaryPath</key>
|
|
@@ -60,18 +63,15 @@
|
|
|
60
63
|
<key>HeadersPath</key>
|
|
61
64
|
<string>Headers</string>
|
|
62
65
|
<key>LibraryIdentifier</key>
|
|
63
|
-
<string>
|
|
66
|
+
<string>tvos-arm64</string>
|
|
64
67
|
<key>LibraryPath</key>
|
|
65
68
|
<string>libForgeKernelFFI.a</string>
|
|
66
69
|
<key>SupportedArchitectures</key>
|
|
67
70
|
<array>
|
|
68
71
|
<string>arm64</string>
|
|
69
|
-
<string>x86_64</string>
|
|
70
72
|
</array>
|
|
71
73
|
<key>SupportedPlatform</key>
|
|
72
|
-
<string>
|
|
73
|
-
<key>SupportedPlatformVariant</key>
|
|
74
|
-
<string>simulator</string>
|
|
74
|
+
<string>tvos</string>
|
|
75
75
|
</dict>
|
|
76
76
|
</array>
|
|
77
77
|
<key>CFBundlePackageType</key>
|
|
Binary file
|
package/ios/ForgeApple/ForgeKernelFFI.xcframework/ios-arm64_x86_64-simulator/libForgeKernelFFI.a
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -481,6 +481,22 @@ fileprivate struct FfiConverterUInt32: FfiConverterPrimitive {
|
|
|
481
481
|
}
|
|
482
482
|
}
|
|
483
483
|
|
|
484
|
+
#if swift(>=5.8)
|
|
485
|
+
@_documentation(visibility: private)
|
|
486
|
+
#endif
|
|
487
|
+
fileprivate struct FfiConverterInt32: FfiConverterPrimitive {
|
|
488
|
+
typealias FfiType = Int32
|
|
489
|
+
typealias SwiftType = Int32
|
|
490
|
+
|
|
491
|
+
public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> Int32 {
|
|
492
|
+
return try lift(readInt(&buf))
|
|
493
|
+
}
|
|
494
|
+
|
|
495
|
+
public static func write(_ value: Int32, into buf: inout [UInt8]) {
|
|
496
|
+
writeInt(&buf, lower(value))
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
|
|
484
500
|
#if swift(>=5.8)
|
|
485
501
|
@_documentation(visibility: private)
|
|
486
502
|
#endif
|
|
@@ -1596,10 +1612,14 @@ public struct AppleDeviceSample: Equatable, Hashable {
|
|
|
1596
1612
|
public var batteryCharging: Bool?
|
|
1597
1613
|
public var thermal: AppleThermalState?
|
|
1598
1614
|
public var diskFreeBytes: UInt64?
|
|
1615
|
+
public var netSignalDbm: Int32?
|
|
1616
|
+
public var netLinkMbps: UInt32?
|
|
1617
|
+
public var netDownlinkKbps: UInt32?
|
|
1618
|
+
public var netFreqMhz: UInt32?
|
|
1599
1619
|
|
|
1600
1620
|
// Default memberwise initializers are never public by default, so we
|
|
1601
1621
|
// declare one manually.
|
|
1602
|
-
public init(sampledAtMs: UInt64, cpuTimeMs: UInt64?, cpuCores: UInt32?, memUsedBytes: UInt64?, memAvailBytes: UInt64?, batteryLevelPct: UInt8?, batteryCharging: Bool?, thermal: AppleThermalState?, diskFreeBytes: UInt64?) {
|
|
1622
|
+
public init(sampledAtMs: UInt64, cpuTimeMs: UInt64?, cpuCores: UInt32?, memUsedBytes: UInt64?, memAvailBytes: UInt64?, batteryLevelPct: UInt8?, batteryCharging: Bool?, thermal: AppleThermalState?, diskFreeBytes: UInt64?, netSignalDbm: Int32?, netLinkMbps: UInt32?, netDownlinkKbps: UInt32?, netFreqMhz: UInt32?) {
|
|
1603
1623
|
self.sampledAtMs = sampledAtMs
|
|
1604
1624
|
self.cpuTimeMs = cpuTimeMs
|
|
1605
1625
|
self.cpuCores = cpuCores
|
|
@@ -1609,6 +1629,10 @@ public struct AppleDeviceSample: Equatable, Hashable {
|
|
|
1609
1629
|
self.batteryCharging = batteryCharging
|
|
1610
1630
|
self.thermal = thermal
|
|
1611
1631
|
self.diskFreeBytes = diskFreeBytes
|
|
1632
|
+
self.netSignalDbm = netSignalDbm
|
|
1633
|
+
self.netLinkMbps = netLinkMbps
|
|
1634
|
+
self.netDownlinkKbps = netDownlinkKbps
|
|
1635
|
+
self.netFreqMhz = netFreqMhz
|
|
1612
1636
|
}
|
|
1613
1637
|
|
|
1614
1638
|
|
|
@@ -1635,7 +1659,11 @@ public struct FfiConverterTypeAppleDeviceSample: FfiConverterRustBuffer {
|
|
|
1635
1659
|
batteryLevelPct: FfiConverterOptionUInt8.read(from: &buf),
|
|
1636
1660
|
batteryCharging: FfiConverterOptionBool.read(from: &buf),
|
|
1637
1661
|
thermal: FfiConverterOptionTypeAppleThermalState.read(from: &buf),
|
|
1638
|
-
diskFreeBytes: FfiConverterOptionUInt64.read(from: &buf)
|
|
1662
|
+
diskFreeBytes: FfiConverterOptionUInt64.read(from: &buf),
|
|
1663
|
+
netSignalDbm: FfiConverterOptionInt32.read(from: &buf),
|
|
1664
|
+
netLinkMbps: FfiConverterOptionUInt32.read(from: &buf),
|
|
1665
|
+
netDownlinkKbps: FfiConverterOptionUInt32.read(from: &buf),
|
|
1666
|
+
netFreqMhz: FfiConverterOptionUInt32.read(from: &buf)
|
|
1639
1667
|
)
|
|
1640
1668
|
}
|
|
1641
1669
|
|
|
@@ -1649,6 +1677,10 @@ public struct FfiConverterTypeAppleDeviceSample: FfiConverterRustBuffer {
|
|
|
1649
1677
|
FfiConverterOptionBool.write(value.batteryCharging, into: &buf)
|
|
1650
1678
|
FfiConverterOptionTypeAppleThermalState.write(value.thermal, into: &buf)
|
|
1651
1679
|
FfiConverterOptionUInt64.write(value.diskFreeBytes, into: &buf)
|
|
1680
|
+
FfiConverterOptionInt32.write(value.netSignalDbm, into: &buf)
|
|
1681
|
+
FfiConverterOptionUInt32.write(value.netLinkMbps, into: &buf)
|
|
1682
|
+
FfiConverterOptionUInt32.write(value.netDownlinkKbps, into: &buf)
|
|
1683
|
+
FfiConverterOptionUInt32.write(value.netFreqMhz, into: &buf)
|
|
1652
1684
|
}
|
|
1653
1685
|
}
|
|
1654
1686
|
|
|
@@ -4099,6 +4131,30 @@ fileprivate struct FfiConverterOptionUInt32: FfiConverterRustBuffer {
|
|
|
4099
4131
|
}
|
|
4100
4132
|
}
|
|
4101
4133
|
|
|
4134
|
+
#if swift(>=5.8)
|
|
4135
|
+
@_documentation(visibility: private)
|
|
4136
|
+
#endif
|
|
4137
|
+
fileprivate struct FfiConverterOptionInt32: FfiConverterRustBuffer {
|
|
4138
|
+
typealias SwiftType = Int32?
|
|
4139
|
+
|
|
4140
|
+
public static func write(_ value: SwiftType, into buf: inout [UInt8]) {
|
|
4141
|
+
guard let value = value else {
|
|
4142
|
+
writeInt(&buf, Int8(0))
|
|
4143
|
+
return
|
|
4144
|
+
}
|
|
4145
|
+
writeInt(&buf, Int8(1))
|
|
4146
|
+
FfiConverterInt32.write(value, into: &buf)
|
|
4147
|
+
}
|
|
4148
|
+
|
|
4149
|
+
public static func read(from buf: inout (data: Data, offset: Data.Index)) throws -> SwiftType {
|
|
4150
|
+
switch try readInt(&buf) as Int8 {
|
|
4151
|
+
case 0: return nil
|
|
4152
|
+
case 1: return try FfiConverterInt32.read(from: &buf)
|
|
4153
|
+
default: throw UniffiInternalError.unexpectedOptionalTag
|
|
4154
|
+
}
|
|
4155
|
+
}
|
|
4156
|
+
}
|
|
4157
|
+
|
|
4102
4158
|
#if swift(>=5.8)
|
|
4103
4159
|
@_documentation(visibility: private)
|
|
4104
4160
|
#endif
|
|
@@ -17,10 +17,10 @@ import Foundation
|
|
|
17
17
|
import UIKit
|
|
18
18
|
#endif
|
|
19
19
|
|
|
20
|
-
/// Thermal pressure on the kernel's normalised ordinal scale (`
|
|
20
|
+
/// Thermal pressure on the kernel's normalised ordinal scale (the `thermal` wire ordinal).
|
|
21
21
|
///
|
|
22
22
|
/// The raw values are the wire ordinals shared with Android, so a Suite
|
|
23
|
-
/// filter on `
|
|
23
|
+
/// filter on `thermal=2` means "serious" on every platform.
|
|
24
24
|
public enum ForgeThermalState: Int, Equatable, CaseIterable {
|
|
25
25
|
case nominal = 0
|
|
26
26
|
case fair = 1
|
|
@@ -52,14 +52,14 @@ public enum ForgeThermalState: Int, Equatable, CaseIterable {
|
|
|
52
52
|
/// cannot read is left `nil`, and the kernel then omits the metric instead of
|
|
53
53
|
/// inventing `0`. The kernel validates field-wise (a battery level above 100,
|
|
54
54
|
/// zero cores or a CPU counter that went backwards is dropped, the rest kept),
|
|
55
|
-
/// derives
|
|
56
|
-
///
|
|
55
|
+
/// derives the CPU rate between two consecutive samples, and emits each
|
|
56
|
+
/// accepted sample as a `device_status` session event.
|
|
57
57
|
public struct ForgeDeviceSample: Equatable {
|
|
58
58
|
/// Wall clock at read time, ms since the Unix epoch. `0` lets the bridge
|
|
59
59
|
/// stamp the call with its own clock.
|
|
60
60
|
public var sampledAtMs: Int64
|
|
61
61
|
/// Cumulative process CPU time, user + system, ms, monotonic over the
|
|
62
|
-
/// process lifetime. Must travel together with ``cpuCores`` for
|
|
62
|
+
/// process lifetime. Must travel together with ``cpuCores`` for the derived CPU rate.
|
|
63
63
|
public var cpuTimeMs: UInt64?
|
|
64
64
|
/// Logical cores available to the process, `>= 1`.
|
|
65
65
|
public var cpuCores: UInt32?
|
|
@@ -79,6 +79,17 @@ public struct ForgeDeviceSample: Equatable {
|
|
|
79
79
|
/// declare the reason can supply the value itself through
|
|
80
80
|
/// `NPAWForge.recordDeviceSample(_:)`.
|
|
81
81
|
public var diskFreeBytes: UInt64?
|
|
82
|
+
/// WiFi signal strength, dBm (negative). **Never filled by Forge on
|
|
83
|
+
/// Apple**: no public RSSI API exists without special entitlements
|
|
84
|
+
/// (`NEHotspotNetwork` needs the hotspot entitlement plus Location;
|
|
85
|
+
/// `CoreWLAN` is macOS-only). Hosts with those grants can supply it.
|
|
86
|
+
public var netSignalDbm: Int32?
|
|
87
|
+
/// Negotiated WiFi PHY link rate, Mbps. Never filled by Forge on Apple.
|
|
88
|
+
public var netLinkMbps: UInt32?
|
|
89
|
+
/// Downstream-bandwidth estimate, kbps. Never filled by Forge on Apple.
|
|
90
|
+
public var netDownlinkKbps: UInt32?
|
|
91
|
+
/// WiFi channel frequency, MHz. Never filled by Forge on Apple.
|
|
92
|
+
public var netFreqMhz: UInt32?
|
|
82
93
|
|
|
83
94
|
public init(
|
|
84
95
|
sampledAtMs: Int64 = 0,
|
|
@@ -89,7 +100,11 @@ public struct ForgeDeviceSample: Equatable {
|
|
|
89
100
|
batteryLevelPct: UInt8? = nil,
|
|
90
101
|
batteryCharging: Bool? = nil,
|
|
91
102
|
thermal: ForgeThermalState? = nil,
|
|
92
|
-
diskFreeBytes: UInt64? = nil
|
|
103
|
+
diskFreeBytes: UInt64? = nil,
|
|
104
|
+
netSignalDbm: Int32? = nil,
|
|
105
|
+
netLinkMbps: UInt32? = nil,
|
|
106
|
+
netDownlinkKbps: UInt32? = nil,
|
|
107
|
+
netFreqMhz: UInt32? = nil
|
|
93
108
|
) {
|
|
94
109
|
self.sampledAtMs = sampledAtMs
|
|
95
110
|
self.cpuTimeMs = cpuTimeMs
|
|
@@ -100,6 +115,10 @@ public struct ForgeDeviceSample: Equatable {
|
|
|
100
115
|
self.batteryCharging = batteryCharging
|
|
101
116
|
self.thermal = thermal
|
|
102
117
|
self.diskFreeBytes = diskFreeBytes
|
|
118
|
+
self.netSignalDbm = netSignalDbm
|
|
119
|
+
self.netLinkMbps = netLinkMbps
|
|
120
|
+
self.netDownlinkKbps = netDownlinkKbps
|
|
121
|
+
self.netFreqMhz = netFreqMhz
|
|
103
122
|
}
|
|
104
123
|
|
|
105
124
|
/// `true` when no metric field is present (only the timestamp).
|
|
@@ -108,6 +127,8 @@ public struct ForgeDeviceSample: Equatable {
|
|
|
108
127
|
&& memUsedBytes == nil && memAvailBytes == nil
|
|
109
128
|
&& batteryLevelPct == nil && batteryCharging == nil
|
|
110
129
|
&& thermal == nil && diskFreeBytes == nil
|
|
130
|
+
&& netSignalDbm == nil && netLinkMbps == nil
|
|
131
|
+
&& netDownlinkKbps == nil && netFreqMhz == nil
|
|
111
132
|
}
|
|
112
133
|
}
|
|
113
134
|
|
|
@@ -119,6 +140,7 @@ public enum ForgeDeviceMetricFamily: String, CaseIterable, Equatable {
|
|
|
119
140
|
case bat
|
|
120
141
|
case thm
|
|
121
142
|
case disk
|
|
143
|
+
case net
|
|
122
144
|
}
|
|
123
145
|
|
|
124
146
|
/// A battery reading exactly as the platform reports it, before shaping.
|
|
@@ -277,7 +299,7 @@ final class ForgeDeviceInsightsCollector {
|
|
|
277
299
|
var sample = ForgeDeviceSample(sampledAtMs: readers.nowMs())
|
|
278
300
|
if requested.contains(.cpu) {
|
|
279
301
|
// The two travel together or not at all: the kernel needs both to
|
|
280
|
-
// derive
|
|
302
|
+
// derive the CPU rate, and half a pair is a value nobody can use.
|
|
281
303
|
if let cpuTimeMs = readers.cpuTimeMs(), let cpuCores = readers.cpuCores() {
|
|
282
304
|
sample.cpuTimeMs = cpuTimeMs
|
|
283
305
|
sample.cpuCores = cpuCores
|
|
@@ -296,6 +318,10 @@ final class ForgeDeviceInsightsCollector {
|
|
|
296
318
|
sample.batteryCharging = fields.charging
|
|
297
319
|
}
|
|
298
320
|
// `disk` is deliberately never read: see ForgeDeviceSample.diskFreeBytes.
|
|
321
|
+
// `net` is deliberately never read either: no public RSSI/link/
|
|
322
|
+
// bandwidth API exists on Apple without entitlements — see
|
|
323
|
+
// ForgeDeviceSample.netSignalDbm. Host-supplied samples pass the
|
|
324
|
+
// fields through.
|
|
299
325
|
|
|
300
326
|
lock.lock()
|
|
301
327
|
let isActive = active
|
|
@@ -78,8 +78,8 @@ public protocol ForgeRuntime: AnyObject {
|
|
|
78
78
|
/// so the three platforms cannot drift into different definitions of moving.
|
|
79
79
|
func recordLocationFix(_ fix: ForgeLocationFix) -> ForgeOutcome
|
|
80
80
|
/// Forwards a device runtime health sample. Every field is optional; the
|
|
81
|
-
/// kernel validates field-wise, derives
|
|
82
|
-
///
|
|
81
|
+
/// kernel validates field-wise, derives the CPU rate between samples and
|
|
82
|
+
/// emits the sample as a `device_status` session event. Refused
|
|
83
83
|
/// (`ignoredInvalidState`) while device insights are off remotely.
|
|
84
84
|
func recordDeviceSample(_ sample: ForgeDeviceSample) -> ForgeOutcome
|
|
85
85
|
/// Registers (or clears with `nil`) the receiver of the kernel's device
|
|
@@ -40,7 +40,7 @@ public final class NPAWForge: NSObject {
|
|
|
40
40
|
/// `scripts/apple/publish-local-shipped.sh` rewrites this literal to the
|
|
41
41
|
/// release version when staging the shipped package, and fails loudly if
|
|
42
42
|
/// it cannot find it. Keep it a plain stored literal for that reason.
|
|
43
|
-
public static let defaultPluginVersion = "10.0.
|
|
43
|
+
public static let defaultPluginVersion = "10.0.4"
|
|
44
44
|
public static let defaultAppName = "apple"
|
|
45
45
|
public static let defaultBuildVariant = "release"
|
|
46
46
|
public static let defaultLmaEndpoint = "https://lma.npaw.com"
|
|
@@ -606,7 +606,11 @@ private func appleDeviceSample(_ sample: ForgeDeviceSample) -> AppleDeviceSample
|
|
|
606
606
|
batteryLevelPct: sample.batteryLevelPct,
|
|
607
607
|
batteryCharging: sample.batteryCharging,
|
|
608
608
|
thermal: sample.thermal.map(appleThermalState),
|
|
609
|
-
diskFreeBytes: sample.diskFreeBytes
|
|
609
|
+
diskFreeBytes: sample.diskFreeBytes,
|
|
610
|
+
netSignalDbm: sample.netSignalDbm,
|
|
611
|
+
netLinkMbps: sample.netLinkMbps,
|
|
612
|
+
netDownlinkKbps: sample.netDownlinkKbps,
|
|
613
|
+
netFreqMhz: sample.netFreqMhz
|
|
610
614
|
)
|
|
611
615
|
}
|
|
612
616
|
|
|
@@ -96,7 +96,15 @@ public struct NetworkRequestRecord: Equatable {
|
|
|
96
96
|
copy.targetUrl = configuration.sanitizeUrl(targetUrl)
|
|
97
97
|
copy.requestQuery = configuration.filterMap(requestQuery, allowlist: configuration.queryAllowlist)
|
|
98
98
|
copy.requestHeaders = configuration.filterMap(requestHeaders, allowlist: configuration.requestHeaderAllowlist)
|
|
99
|
-
|
|
99
|
+
// The cache-stat headers ride beside the host allowlist so the
|
|
100
|
+
// kernel's network_stats cache counters can classify; their values
|
|
101
|
+
// reach the raw-event wire only when the remote `nc.sh` allowlist
|
|
102
|
+
// names them.
|
|
103
|
+
copy.responseHeaders = configuration.filterMap(
|
|
104
|
+
responseHeaders,
|
|
105
|
+
allowlist: configuration.responseHeaderAllowlist
|
|
106
|
+
.union(NetworkPrivacyConfiguration.cacheStatsResponseHeaders)
|
|
107
|
+
)
|
|
100
108
|
copy.errorMessage = errorMessage.map(configuration.sanitizeText)
|
|
101
109
|
return copy
|
|
102
110
|
}
|
|
@@ -123,6 +131,19 @@ public struct NetworkPrivacyConfiguration: Equatable {
|
|
|
123
131
|
self.maxStringLength = max(1, maxStringLength)
|
|
124
132
|
}
|
|
125
133
|
|
|
134
|
+
/// Response headers the kernel's cache hit/miss statistics classify
|
|
135
|
+
/// (`network_stats` cacheHits/cacheMisses per tier). Always kept beside
|
|
136
|
+
/// `responseHeaderAllowlist`; values carry CDN node hostnames, never
|
|
137
|
+
/// user data, and hit the raw-event wire only when the remote `nc.sh`
|
|
138
|
+
/// allowlist names them.
|
|
139
|
+
public static let cacheStatsResponseHeaders: Set<String> = [
|
|
140
|
+
"cache-status",
|
|
141
|
+
"cf-cache-status",
|
|
142
|
+
"x-cache-status",
|
|
143
|
+
"x-cache",
|
|
144
|
+
"x-cache-remote",
|
|
145
|
+
]
|
|
146
|
+
|
|
126
147
|
public static let defaultRedactionKeys: Set<String> = [
|
|
127
148
|
"authorization",
|
|
128
149
|
"proxy-authorization",
|
|
@@ -125,6 +125,23 @@ static void NPAWEmit(NSURLRequest *request, NSURLResponse *response, NSData *dat
|
|
|
125
125
|
if (http.MIMEType.length > 0) {
|
|
126
126
|
payload[@"responseHeader.Content-Type"] = http.MIMEType;
|
|
127
127
|
}
|
|
128
|
+
// Cache-stat headers for the kernel's network_stats hit/miss counters.
|
|
129
|
+
// -valueForHTTPHeaderField: is case-insensitive and comma-joins repeated
|
|
130
|
+
// lines, so multi-hop X-Cache chains arrive whole. The values only reach
|
|
131
|
+
// the raw-event wire when the remote allowlist names them.
|
|
132
|
+
NSArray<NSString *> *cacheHeaderNames = @[
|
|
133
|
+
@"Cache-Status",
|
|
134
|
+
@"CF-Cache-Status",
|
|
135
|
+
@"X-Cache-Status",
|
|
136
|
+
@"X-Cache",
|
|
137
|
+
@"X-Cache-Remote",
|
|
138
|
+
];
|
|
139
|
+
for (NSString *headerName in cacheHeaderNames) {
|
|
140
|
+
NSString *headerValue = [http valueForHTTPHeaderField:headerName];
|
|
141
|
+
if (headerValue.length > 0) {
|
|
142
|
+
payload[[@"responseHeader." stringByAppendingString:headerName]] = headerValue;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
128
145
|
callback(payload);
|
|
129
146
|
}
|
|
130
147
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@npaw/forge-react-native",
|
|
3
|
-
"version": "10.0.
|
|
3
|
+
"version": "10.0.4",
|
|
4
4
|
"description": "NPAW Forge analytics for React Native: New Architecture TurboModule facade over the native Forge Android/Apple SDKs.",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE",
|
|
6
6
|
"author": "Victor Soto <victor.soto@nicepeopleatwork.com>",
|