Skip to content
Prev Previous commit
Next Next commit
feat: respect be network body limit (#1397)
* chore(ios): add respect BE network body limit custom build * feat(ios): add getNetworkBodyMaxSize API * feat:add getNetworkBodyMaxSize API * chore(android): add respect network body limit snapshot * chore(ios): sync pdfile.lock * Revert "Merge pull request #1388 from Instabug/refactor/replace-reflection" This reverts commit 256e72a, reversing changes made to 196b481. * feat(android): add getNetworkBodyMaxSize API * feat:add feature flag change listener for android * chore: fix sync_generated_files CI job * feat(ios): add getNetworkBodyMaxSize API * chore: add change log * Revert duplicate "feat(ios): add getNetworkBodyMaxSize API" This reverts commit ef8710e. * chore: edit a change log * chore: update test cases titles
  • Loading branch information
kholood-ea committed Jul 1, 2025
commit 83c5b9e3daddf54e013ca77661bfa774e0cd9ebc
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

- Add support for network spans. ([#1394](https://github.com/Instabug/Instabug-React-Native/pull/1394))

- Add respect to backend network body limit. ([#1397](https://github.com/Instabug/Instabug-React-Native/pull/1397))

### Changed

- Bump Instabug iOS SDK to v15.1.1 ([#1402](https://github.com/Instabug/Instabug-React-Native/pull/1402)). [See release notes](https://github.com/Instabug/Instabug-iOS/releases/tag/15.1.1).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ final class Constants {
final static String IBG_ON_FEATURES_UPDATED_CALLBACK = "IBGOnFeatureUpdatedCallback";
final static String IBG_NETWORK_LOGGER_HANDLER = "IBGNetworkLoggerHandler";

final static String IBG_ON_NEW_W3C_FLAGS_UPDATE_RECEIVED_CALLBACK = "IBGOnNewW3CFlagsUpdateReceivedCallback";
final static String IBG_ON_FEATURE_FLAGS_UPDATE_RECEIVED_CALLBACK = "IBGOnNewFeatureFlagsUpdateReceivedCallback";

final static String IBG_SESSION_REPLAY_ON_SYNC_CALLBACK_INVOCATION = "IBGSessionReplayOnSyncCallback";

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1159,10 +1159,10 @@ public void run() {
}

/**
* Register a listener for W3C flags value change
* Register a listener for feature flags value change
*/
@ReactMethod
public void registerW3CFlagsChangeListener() {
public void registerFeatureFlagsChangeListener() {

MainThreadHandler.runOnMainThread(new Runnable() {
@Override
Expand All @@ -1175,8 +1175,9 @@ public void invoke(@NonNull CoreFeaturesState featuresState) {
params.putBoolean("isW3ExternalTraceIDEnabled", featuresState.isW3CExternalTraceIdEnabled());
params.putBoolean("isW3ExternalGeneratedHeaderEnabled", featuresState.isAttachingGeneratedHeaderEnabled());
params.putBoolean("isW3CaughtHeaderEnabled", featuresState.isAttachingCapturedHeaderEnabled());
params.putInt("networkBodyLimit",featuresState.getNetworkLogCharLimit());

sendEvent(Constants.IBG_ON_NEW_W3C_FLAGS_UPDATE_RECEIVED_CALLBACK, params);
sendEvent(Constants.IBG_ON_FEATURE_FLAGS_UPDATE_RECEIVED_CALLBACK, params);
}
});
} catch (Exception e) {
Expand Down Expand Up @@ -1306,7 +1307,7 @@ public void run() {
}
});
}
/**

/**
* Sets the auto mask screenshots types.
*
Expand All @@ -1331,4 +1332,23 @@ public void run() {

});
}

/**
* Get network body size limit
*/
@ReactMethod
public void getNetworkBodyMaxSize(Promise promise) {

MainThreadHandler.runOnMainThread(new Runnable() {
@Override
public void run() {
try {
promise.resolve(InternalCore.INSTANCE.get_networkLogCharLimit());
} catch (Exception e) {
e.printStackTrace();
promise.resolve(false);
}
}
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -686,9 +686,22 @@ public void testEnableAutoMasking(){
String maskTextInputs = "textInputs";
String maskMedia = "media";
String maskNone = "none";

rnModule.enableAutoMasking(JavaOnlyArray.of(maskLabel, maskMedia, maskTextInputs,maskNone));

mockInstabug.verify(() -> Instabug.setAutoMaskScreenshotsTypes(MaskingType.LABELS,MaskingType.MEDIA,MaskingType.TEXT_INPUTS,MaskingType.MASK_NOTHING));
}

@Test
public void testGetNetworkBodyMaxSize_resolvesPromiseWithExpectedValue() {
Promise promise = mock(Promise.class);
InternalCore internalAPM = mock(InternalCore.class);
int expected = 10240;
when(internalAPM.get_networkLogCharLimit()).thenReturn(expected);

rnModule.getNetworkBodyMaxSize(promise);

verify(promise).resolve(expected);
}

}
19 changes: 19 additions & 0 deletions examples/default/ios/InstabugTests/InstabugSampleTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -634,4 +634,23 @@ - (void)testSetNetworkLogBodyEnabled {
OCMVerify([mock setLogBodyEnabled:isEnabled]);
}

- (void)testGetNetworkBodyMaxSize {
id mock = OCMClassMock([IBGNetworkLogger class]);
double expectedValue = 10240.0;

OCMStub([mock getNetworkBodyMaxSize]).andReturn(expectedValue);

XCTestExpectation *expectation = [self expectationWithDescription:@"Call resolve block"];
RCTPromiseResolveBlock resolve = ^(NSNumber *result) {
XCTAssertEqual(result.doubleValue, expectedValue);
[expectation fulfill];
};

[self.instabugBridge getNetworkBodyMaxSize:resolve :nil];
[self waitForExpectationsWithTimeout:1.0 handler:nil];

OCMVerify(ClassMethod([mock getNetworkBodyMaxSize]));
}


@end
2 changes: 1 addition & 1 deletion examples/default/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export const App: React.FC = () => {
token: 'deb1910a7342814af4e4c9210c786f35',
invocationEvents: [InvocationEvent.floatingButton],
debugLogsLevel: LogLevel.verbose,
networkInterceptionMode: NetworkInterceptionMode.native,
networkInterceptionMode: NetworkInterceptionMode.javascript,
});

CrashReporting.setNDKCrashesEnabled(true);
Expand Down
1 change: 1 addition & 0 deletions ios/RNInstabug/InstabugReactBridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -140,5 +140,6 @@ w3cExternalTraceAttributes:(NSDictionary * _Nullable)w3cExternalTraceAttributes;
- (void)removeAllFeatureFlags;
- (void)setNetworkLogBodyEnabled:(BOOL)isEnabled;
- (void)enableAutoMasking:(NSArray *)autoMaskingTypes;
- (void)getNetworkBodyMaxSize:(RCTPromiseResolveBlock)resolve :(RCTPromiseRejectBlock)reject;

@end
4 changes: 4 additions & 0 deletions ios/RNInstabug/InstabugReactBridge.m
Original file line number Diff line number Diff line change
Expand Up @@ -452,6 +452,10 @@ + (BOOL)iOSVersionIsLessThan:(NSString *)iOSVersion {
[Instabug setAutoMaskScreenshots: autoMaskingOptions];
};

RCT_EXPORT_METHOD(getNetworkBodyMaxSize:(RCTPromiseResolveBlock)resolve :(RCTPromiseRejectBlock)reject) {
resolve(@(IBGNetworkLogger.getNetworkBodyMaxSize));
}

RCT_EXPORT_METHOD(setNetworkLogBodyEnabled:(BOOL)isEnabled) {
IBGNetworkLogger.logBodyEnabled = isEnabled;
}
Expand Down
1 change: 1 addition & 0 deletions ios/RNInstabug/Util/IBGNetworkLogger+CP.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ NS_ASSUME_NONNULL_BEGIN
+ (void)setCPRequestAsyncObfuscationHandler:(void (^)(NSURLRequest * requestToBeObfuscated, void (^ completion)(NSURLRequest * obfuscatedRequest)))asyncObfuscationHandler;
+ (void)setCPRequestFilteringHandler:(void (^)(NSURLRequest * request, void (^completion)(BOOL keep)))requestFilteringHandler;
+ (void)setCPResponseFilteringHandler:(void (^)(NSURLResponse * response, void (^comppletion)(BOOL keep)))responseFilteringHandler;
+ (double)getNetworkBodyMaxSize;

@end

Expand Down
13 changes: 7 additions & 6 deletions src/modules/Instabug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import type { NavigationAction, NavigationState as NavigationStateV4 } from 'rea
import type { InstabugConfig } from '../models/InstabugConfig';
import Report from '../models/Report';
import { emitter, NativeEvents, NativeInstabug } from '../native/NativeInstabug';
import { registerW3CFlagsListener } from '../utils/FeatureFlags';
import { registerFeatureFlagsListener } from '../utils/FeatureFlags';
import {
AutoMaskingType,
ColorTheme,
Expand Down Expand Up @@ -87,7 +87,7 @@ function reportCurrentViewForAndroid(screenName: string | null) {
export const init = async (config: InstabugConfig) => {
if (Platform.OS === 'android') {
// Add android feature flags listener for android
registerW3CFlagsListener();
registerFeatureFlagsListener();
addOnFeatureUpdatedListener(config);
} else {
isNativeInterceptionFeatureEnabled = await NativeNetworkLogger.isNativeInterceptionEnabled();
Expand Down Expand Up @@ -871,20 +871,21 @@ export const componentDidAppearListener = (event: ComponentDidAppearEvent) => {
};

/**
* Sets listener to W3ExternalTraceID flag changes
* Sets listener to feature flag changes
* @param handler A callback that gets the update value of the flag
*/
export const _registerW3CFlagsChangeListener = (
export const _registerFeatureFlagsChangeListener = (
handler: (payload: {
isW3ExternalTraceIDEnabled: boolean;
isW3ExternalGeneratedHeaderEnabled: boolean;
isW3CaughtHeaderEnabled: boolean;
networkBodyLimit: number;
}) => void,
) => {
emitter.addListener(NativeEvents.ON_W3C_FLAGS_CHANGE, (payload) => {
emitter.addListener(NativeEvents.ON_FEATURE_FLAGS_CHANGE, (payload) => {
handler(payload);
});
NativeInstabug.registerW3CFlagsChangeListener();
NativeInstabug.registerFeatureFlagsChangeListener();
};

/**
Expand Down
28 changes: 22 additions & 6 deletions src/modules/NetworkLogger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ export const setEnabled = (isEnabled: boolean) => {
xhr.setOnDoneCallback(async (network) => {
// eslint-disable-next-line no-new-func
const predicate = Function('network', 'return ' + _requestFilterExpression);

if (!predicate(network)) {
const MAX_NETWORK_BODY_SIZE_IN_BYTES = await NativeInstabug.getNetworkBodyMaxSize();
try {
if (_networkDataObfuscationHandler) {
network = await _networkDataObfuscationHandler(network);
Expand All @@ -57,14 +59,28 @@ export const setEnabled = (isEnabled: boolean) => {
return;
}
}
if (network.requestBodySize > InstabugConstants.MAX_NETWORK_BODY_SIZE_IN_BYTES) {
network.requestBody = InstabugConstants.MAX_REQUEST_BODY_SIZE_EXCEEDED_MESSAGE;
Logger.warn('IBG-RN:', InstabugConstants.MAX_REQUEST_BODY_SIZE_EXCEEDED_MESSAGE);
if (network.requestBodySize > MAX_NETWORK_BODY_SIZE_IN_BYTES) {
network.requestBody = `${InstabugConstants.MAX_REQUEST_BODY_SIZE_EXCEEDED_MESSAGE}${
MAX_NETWORK_BODY_SIZE_IN_BYTES / 1024
} Kb`;
Logger.warn(
'IBG-RN:',
`${InstabugConstants.MAX_REQUEST_BODY_SIZE_EXCEEDED_MESSAGE}${
MAX_NETWORK_BODY_SIZE_IN_BYTES / 1024
} Kb`,
);
}

if (network.responseBodySize > InstabugConstants.MAX_NETWORK_BODY_SIZE_IN_BYTES) {
network.responseBody = InstabugConstants.MAX_RESPONSE_BODY_SIZE_EXCEEDED_MESSAGE;
Logger.warn('IBG-RN:', InstabugConstants.MAX_RESPONSE_BODY_SIZE_EXCEEDED_MESSAGE);
if (network.responseBodySize > MAX_NETWORK_BODY_SIZE_IN_BYTES) {
network.responseBody = `${InstabugConstants.MAX_RESPONSE_BODY_SIZE_EXCEEDED_MESSAGE}${
MAX_NETWORK_BODY_SIZE_IN_BYTES / 1024
} Kb`;
Logger.warn(
'IBG-RN:',
`${InstabugConstants.MAX_RESPONSE_BODY_SIZE_EXCEEDED_MESSAGE}${
MAX_NETWORK_BODY_SIZE_IN_BYTES / 1024
} Kb`,
);
}

if (network.requestBody && isContentTypeNotAllowed(network.requestContentType)) {
Expand Down
7 changes: 4 additions & 3 deletions src/native/NativeInstabug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,19 +152,20 @@ export interface InstabugNativeModule extends NativeModule {

isW3CaughtHeaderEnabled(): Promise<boolean>;

// W3C Feature Flags Listener for Android
registerW3CFlagsChangeListener(): void;
// Feature Flags Listener for Android
registerFeatureFlagsChangeListener(): void;

setOnFeaturesUpdatedListener(handler?: (params: any) => void): void; // android only
enableAutoMasking(autoMaskingTypes: AutoMaskingType[]): void;
getNetworkBodyMaxSize(): Promise<number>;
}

export const NativeInstabug = NativeModules.Instabug;

export enum NativeEvents {
PRESENDING_HANDLER = 'IBGpreSendingHandler',
IBG_ON_FEATURES_UPDATED_CALLBACK = 'IBGOnFeatureUpdatedCallback',
ON_W3C_FLAGS_CHANGE = 'IBGOnNewW3CFlagsUpdateReceivedCallback',
ON_FEATURE_FLAGS_CHANGE = 'IBGOnNewFeatureFlagsUpdateReceivedCallback',
}

export const emitter = new NativeEventEmitter(NativeInstabug);
11 changes: 8 additions & 3 deletions src/utils/FeatureFlags.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import { NativeInstabug } from '../native/NativeInstabug';
import { _registerW3CFlagsChangeListener } from '../modules/Instabug';
import { _registerFeatureFlagsChangeListener } from '../modules/Instabug';

export const FeatureFlags = {
isW3ExternalTraceID: () => NativeInstabug.isW3ExternalTraceIDEnabled(),
isW3ExternalGeneratedHeader: () => NativeInstabug.isW3ExternalGeneratedHeaderEnabled(),
isW3CaughtHeader: () => NativeInstabug.isW3CaughtHeaderEnabled(),
networkLogLimit: () => NativeInstabug.getNetworkBodyMaxSize(),
};

export const registerW3CFlagsListener = () => {
_registerW3CFlagsChangeListener(
export const registerFeatureFlagsListener = () => {
_registerFeatureFlagsChangeListener(
(res: {
isW3ExternalTraceIDEnabled: boolean;
isW3ExternalGeneratedHeaderEnabled: boolean;
isW3CaughtHeaderEnabled: boolean;
networkBodyLimit: number;
}) => {
FeatureFlags.isW3ExternalTraceID = async () => {
return res.isW3ExternalTraceIDEnabled;
Expand All @@ -23,6 +25,9 @@ export const registerW3CFlagsListener = () => {
FeatureFlags.isW3CaughtHeader = async () => {
return res.isW3CaughtHeaderEnabled;
};
FeatureFlags.networkLogLimit = async () => {
return res.networkBodyLimit;
};
},
);
};
4 changes: 2 additions & 2 deletions src/utils/InstabugConstants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ const InstabugConstants = {
// TODO: dyanmically get the max size from the native SDK and update the error message to reflect the dynamic size.
MAX_NETWORK_BODY_SIZE_IN_BYTES: 1024 * 10, // 10 KB
MAX_RESPONSE_BODY_SIZE_EXCEEDED_MESSAGE:
'The response body has not been logged because it exceeds the maximum size of 10 Kb',
'The response body has not been logged because it exceeds the maximum size of ',
MAX_REQUEST_BODY_SIZE_EXCEEDED_MESSAGE:
'The request body has not been logged because it exceeds the maximum size of 10 Kb',
'The request body has not been logged because it exceeds the maximum size of ',
SET_USER_ATTRIBUTES_ERROR_TYPE_MESSAGE:
'IBG-RN: Expected key and value passed to setUserAttribute to be of type string',
REMOVE_USER_ATTRIBUTES_ERROR_TYPE_MESSAGE:
Expand Down
3 changes: 2 additions & 1 deletion test/mocks/mockInstabug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,10 +72,11 @@ const mockInstabug: InstabugNativeModule = {
isW3ExternalTraceIDEnabled: jest.fn(),
isW3ExternalGeneratedHeaderEnabled: jest.fn(),
isW3CaughtHeaderEnabled: jest.fn(),
registerW3CFlagsChangeListener: jest.fn(),
registerFeatureFlagsChangeListener: jest.fn(),
setNetworkLogBodyEnabled: jest.fn(),
setOnFeaturesUpdatedListener: jest.fn(),
enableAutoMasking: jest.fn(),
getNetworkBodyMaxSize: jest.fn().mockResolvedValue(10240), // 10 KB
};

export default mockInstabug;
14 changes: 7 additions & 7 deletions test/modules/Instabug.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -900,19 +900,19 @@ describe('Instabug Module', () => {
expect(NativeInstabug.willRedirectToStore).toBeCalledTimes(1);
});

it('should register W3C flag listener', async () => {
it('should register feature flag listener', async () => {
const callback = jest.fn();
Instabug._registerW3CFlagsChangeListener(callback);
Instabug._registerFeatureFlagsChangeListener(callback);

expect(NativeInstabug.registerW3CFlagsChangeListener).toBeCalledTimes(1);
expect(NativeInstabug.registerFeatureFlagsChangeListener).toBeCalledTimes(1);
});

it('should invoke callback on emitting the event IBGOnNewW3CFlagsUpdateReceivedCallback', () => {
it('should invoke callback on emitting the event IBGOnNewFeatureFlagsUpdateReceivedCallback', () => {
const callback = jest.fn();
Instabug._registerW3CFlagsChangeListener(callback);
emitter.emit(NativeEvents.ON_W3C_FLAGS_CHANGE);
Instabug._registerFeatureFlagsChangeListener(callback);
emitter.emit(NativeEvents.ON_FEATURE_FLAGS_CHANGE);

expect(emitter.listenerCount(NativeEvents.ON_W3C_FLAGS_CHANGE)).toBe(1);
expect(emitter.listenerCount(NativeEvents.ON_FEATURE_FLAGS_CHANGE)).toBe(1);
expect(callback).toHaveBeenCalled();
});

Expand Down
Loading