Skip to content

Commit 6e82cb7

Browse files
[FSSDK-11938] custom header (#1092)
1 parent 7e89e43 commit 6e82cb7

File tree

4 files changed

+57
-1
lines changed

4 files changed

+57
-1
lines changed

lib/modules/datafile-manager/datafileManager.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ export interface DatafileManagerConfig {
4444
updateInterval?: number;
4545
urlTemplate?: string;
4646
cache?: PersistentKeyValueCache;
47+
customHeaders?: Record<string, string>;
4748
}
4849

4950
export interface NodeDatafileManagerConfig extends DatafileManagerConfig {

lib/modules/datafile-manager/httpPollingDatafileManager.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
*/
1616

1717
import { getLogger } from '../logging';
18-
import { sprintf } from '../../utils/fns';
18+
import { sprintf, assign } from '../../utils/fns';
1919
import { DatafileManager, DatafileManagerConfig, DatafileUpdate } from './datafileManager';
2020
import EventEmitter, { Disposer } from './eventEmitter';
2121
import { AbortableRequest, Response, Headers } from './http';
@@ -96,6 +96,8 @@ export default abstract class HttpPollingDatafileManager implements DatafileMana
9696

9797
private sdkKey: string;
9898

99+
private customHeaders?: Record<string, string>;
100+
99101
// When true, this means the update interval timeout fired before the current
100102
// sync completed. In that case, we should sync again immediately upon
101103
// completion of the current request, instead of waiting another update
@@ -114,11 +116,13 @@ export default abstract class HttpPollingDatafileManager implements DatafileMana
114116
updateInterval = DEFAULT_UPDATE_INTERVAL,
115117
urlTemplate = DEFAULT_URL_TEMPLATE,
116118
cache = noOpKeyValueCache,
119+
customHeaders,
117120
} = configWithDefaultsApplied;
118121

119122
this.cache = cache;
120123
this.cacheKey = 'opt-datafile-' + sdkKey;
121124
this.sdkKey = sdkKey;
125+
this.customHeaders = customHeaders;
122126
this.isReadyPromiseSettled = false;
123127
this.readyPromiseResolver = (): void => { };
124128
this.readyPromiseRejecter = (): void => { };
@@ -266,6 +270,11 @@ export default abstract class HttpPollingDatafileManager implements DatafileMana
266270

267271
private syncDatafile(): void {
268272
const headers: Headers = {};
273+
274+
if (this.customHeaders) {
275+
assign(headers, this.customHeaders);
276+
}
277+
269278
if (this.lastResponseLastModified) {
270279
headers['if-modified-since'] = this.lastResponseLastModified;
271280
}

lib/shared_types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ export interface DatafileOptions {
9595
updateInterval?: number;
9696
urlTemplate?: string;
9797
datafileAccessToken?: string;
98+
customHeaders?: Record<string, string>;
9899
}
99100

100101
export interface OdpOptions {

tests/nodeDatafileManager.spec.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,4 +183,49 @@ describe('nodeDatafileManager', () => {
183183
expect(makeGetRequestSpy).toBeCalledWith('https://myawesomeurl/', expect.anything());
184184
await manager.stop();
185185
});
186+
187+
it('passes custom headers to makeGetRequest and merges with system headers', async () => {
188+
makeGetRequestSpy.mockReturnValue({
189+
abort: jest.fn(),
190+
responsePromise: Promise.resolve({
191+
statusCode: 200,
192+
body: '{"foo":"bar"}',
193+
headers: {
194+
'last-modified': 'Fri, 08 Mar 2019 18:57:17 GMT',
195+
},
196+
}),
197+
});
198+
const manager = new NodeDatafileManager({
199+
sdkKey: '1234',
200+
autoUpdate: true,
201+
customHeaders: {
202+
'X-Custom-Header': 'custom-value',
203+
'X-Environment': 'production',
204+
},
205+
});
206+
manager.start();
207+
await manager.onReady();
208+
209+
// First request should have custom headers
210+
expect(makeGetRequestSpy).toBeCalledTimes(1);
211+
expect(makeGetRequestSpy.mock.calls[0][0]).toBe('https://cdn.optimizely.com/datafiles/1234.json');
212+
expect(makeGetRequestSpy.mock.calls[0][1]).toEqual({
213+
'X-Custom-Header': 'custom-value',
214+
'X-Environment': 'production',
215+
});
216+
217+
// Advance time to trigger second request
218+
await advanceTimersByTime(300000);
219+
220+
// Second request should have both custom headers AND if-modified-since
221+
expect(makeGetRequestSpy).toBeCalledTimes(2);
222+
expect(makeGetRequestSpy.mock.calls[1][0]).toBe('https://cdn.optimizely.com/datafiles/1234.json');
223+
expect(makeGetRequestSpy.mock.calls[1][1]).toEqual({
224+
'X-Custom-Header': 'custom-value',
225+
'X-Environment': 'production',
226+
'if-modified-since': 'Fri, 08 Mar 2019 18:57:17 GMT',
227+
});
228+
229+
await manager.stop();
230+
});
186231
});

0 commit comments

Comments
 (0)