Skip to content

Commit 2f9dd3c

Browse files
Merge branch 'javascript_client_issue_847' into refactor_for_strict_mode
2 parents 5da17c4 + 9afd29f commit 2f9dd3c

16 files changed

+49
-32
lines changed

CHANGES.txt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1-
2.0.1 (XXX XX, 2024)
2-
- Updated the factory `init` and `destroy` methods to support re-initialization after destruction, enabling repeated cycles of initialization and cleanup. This update ensures compatibility of the React SDK with React Strict Mode, where the factory's `init` and `destroy` effects are executed an extra time to validate proper resource cleanup.
1+
2.0.2 (XXX XX, 2024)
2+
- Updated the factory `init` and `destroy` methods to support re-initialization after destruction. This update ensures compatibility of the React SDK with React Strict Mode, where the factory's `init` and `destroy` effects are executed an extra time to validate proper resource cleanup.
3+
- Bugfixing - Sanitize the `SplitSDKMachineName` header value to avoid exceptions on HTTP/S requests when it contains non ISO-8859-1 characters (Related to issue https://github.com/splitio/javascript-client/issues/847).
4+
5+
2.0.1 (November 25, 2024)
6+
- Bugfixing - Fixed an issue with the SDK_UPDATE event on server-side, where it was not being emitted if there was an empty segment and the SDK received a feature flag update notification.
37

48
2.0.0 (November 1, 2024)
59
- Added support for targeting rules based on large segments.

package-lock.json

Lines changed: 6 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/services/__tests__/decorateHeaders.spec.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { ISettings } from '../../types';
2-
import { decorateHeaders } from '../decorateHeaders';
2+
import { decorateHeaders, removeNonISO88591 } from '../decorateHeaders';
33

44
const HEADERS = {
55
Authorization: 'Bearer SDK-KEY',
@@ -48,3 +48,10 @@ describe('decorateHeaders', () => {
4848
expect(settings.log.error).toHaveBeenCalledWith('Problem adding custom headers to request decorator: Error: Unexpected error');
4949
});
5050
});
51+
52+
test('removeNonISO88591', () => {
53+
expect(removeNonISO88591('')).toBe('');
54+
expect(removeNonISO88591('This is a test')).toBe('This is a test');
55+
expect(removeNonISO88591('This is a test ó \u0FFF 你')).toBe('This is a test ó ');
56+
expect(removeNonISO88591('Emiliano’s-MacBook-Pro')).toBe('Emilianos-MacBook-Pro');
57+
});

src/services/decorateHeaders.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,8 @@ export function decorateHeaders(settings: ISettings, headers: Record<string, str
3030
}
3131
return headers;
3232
}
33+
34+
export function removeNonISO88591(input: string) {
35+
// eslint-disable-next-line no-control-regex
36+
return input.replace(/[^\x00-\xFF]/g, '');
37+
}

src/services/splitHttpClient.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { objectAssign } from '../utils/lang/objectAssign';
33
import { ERROR_HTTP, ERROR_CLIENT_CANNOT_GET_READY } from '../logger/constants';
44
import { ISettings } from '../types';
55
import { IPlatform } from '../sdkFactory/types';
6-
import { decorateHeaders } from './decorateHeaders';
6+
import { decorateHeaders, removeNonISO88591 } from './decorateHeaders';
77

88
const messageNoFetch = 'Global fetch API is not available.';
99

@@ -30,7 +30,7 @@ export function splitHttpClientFactory(settings: ISettings, { getOptions, getFet
3030
};
3131

3232
if (ip) commonHeaders['SplitSDKMachineIP'] = ip;
33-
if (hostname) commonHeaders['SplitSDKMachineName'] = hostname;
33+
if (hostname) commonHeaders['SplitSDKMachineName'] = removeNonISO88591(hostname);
3434

3535
return function httpClient(url: string, reqOpts: IRequestOptions = {}, latencyTracker: (error?: NetworkError) => void = () => { }, logErrorsAsInfo: boolean = false): Promise<IResponse> {
3636

src/storages/AbstractMySegmentsCacheSync.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export abstract class AbstractMySegmentsCacheSync implements ISegmentsCacheSync
4242
// @TODO for client-side it should be the number of clients, but it requires a refactor of MySegments caches to simplify the code.
4343
abstract getKeysCount(): number
4444

45-
abstract getChangeNumber(name: string): number
45+
abstract getChangeNumber(): number
4646

4747
/**
4848
* For server-side synchronizer: the method is not used.

src/storages/inMemory/SegmentsCacheInMemory.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ export class SegmentsCacheInMemory implements ISegmentsCacheSync {
6565
getChangeNumber(name: string) {
6666
const value = this.segmentChangeNumber[name];
6767

68-
return isIntegerNumber(value) ? value : -1;
68+
return isIntegerNumber(value) ? value : undefined;
6969
}
7070

7171
// No-op. Not used in server-side

src/storages/inRedis/SegmentsCacheInRedis.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,10 @@ export class SegmentsCacheInRedis implements ISegmentsCacheAsync {
4444
return this.redis.get(this.keys.buildSegmentTillKey(name)).then((value: string | null) => {
4545
const i = parseInt(value as string, 10);
4646

47-
return isNaNNumber(i) ? -1 : i;
47+
return isNaNNumber(i) ? undefined : i;
4848
}).catch((e) => {
4949
this.log.error(LOG_PREFIX + 'Could not retrieve changeNumber from segments storage. Error: ' + e);
50-
return -1;
50+
return undefined;
5151
});
5252
}
5353

src/storages/inRedis/__tests__/SegmentsCacheInRedis.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ describe('SEGMENTS CACHE IN REDIS', () => {
1717

1818
expect(await cache.getChangeNumber('mocked-segment') === 1).toBe(true);
1919

20-
expect(await cache.getChangeNumber('inexistent-segment')).toBe(-1); // -1 if the segment doesn't exist
20+
expect(await cache.getChangeNumber('inexistent-segment')).toBe(undefined); // -1 if the segment doesn't exist
2121

2222
await cache.update('mocked-segment', ['d', 'e'], [], 2);
2323

src/storages/pluggable/SegmentsCachePluggable.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,10 +55,10 @@ export class SegmentsCachePluggable implements ISegmentsCacheAsync {
5555
return this.wrapper.get(this.keys.buildSegmentTillKey(name)).then((value: string | null) => {
5656
const i = parseInt(value as string, 10);
5757

58-
return isNaNNumber(i) ? -1 : i;
58+
return isNaNNumber(i) ? undefined : i;
5959
}).catch((e) => {
6060
this.log.error(LOG_PREFIX + 'Could not retrieve changeNumber from segments storage. Error: ' + e);
61-
return -1;
61+
return undefined;
6262
});
6363
}
6464

0 commit comments

Comments
 (0)