Skip to content

Commit 537c8cf

Browse files
authored
Merge pull request #492 from splitio/fix/custom_header_overrides
fix header overrides
2 parents 13bcbd4 + c81ea7e commit 537c8cf

File tree

13 files changed

+583
-319
lines changed

13 files changed

+583
-319
lines changed

client/src/main/java/io/split/client/RequestDecorator.java

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
import io.split.client.dtos.RequestContext;
44

5-
import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase;
5+
//`import org.apache.hc.client5.http.classic.methods.HttpUriRequestBase;
6+
import org.apache.hc.core5.http.HttpRequest;
67
import org.apache.hc.core5.http.Header;
78

89
import java.util.HashSet;
@@ -13,8 +14,10 @@
1314
import java.util.Set;
1415
import java.util.List;
1516

16-
class NoOpHeaderDecorator implements CustomHeaderDecorator {
17-
public NoOpHeaderDecorator() {}
17+
class NoOpHeaderDecorator implements CustomHeaderDecorator {
18+
public NoOpHeaderDecorator() {
19+
}
20+
1821
@Override
1922
public Map<String, List<String>> getHeaderOverrides(RequestContext context) {
2023
return new HashMap<>();
@@ -36,32 +39,33 @@ public final class RequestDecorator {
3639
"content-encoding",
3740
"accept",
3841
"keep-alive",
39-
"x-fastly-debug"
40-
));
42+
"x-fastly-debug"));
4143

4244
public RequestDecorator(CustomHeaderDecorator headerDecorator) {
4345
_headerDecorator = (headerDecorator == null)
4446
? new NoOpHeaderDecorator()
4547
: headerDecorator;
4648
}
4749

48-
public HttpUriRequestBase decorateHeaders(HttpUriRequestBase request) {
50+
public HttpRequest decorateHeaders(HttpRequest request) {
4951
try {
50-
Map<String, List<String>> headers = _headerDecorator.getHeaderOverrides(new RequestContext(convertToMap(request.getHeaders())));
51-
for (Map.Entry entry : headers.entrySet()) {
52-
if (isHeaderAllowed(entry.getKey().toString())) {
53-
List<String> values = (List<String>) entry.getValue();
52+
Map<String, List<String>> headers = _headerDecorator
53+
.getHeaderOverrides(new RequestContext(convertToMap(request.getHeaders())));
54+
for (Map.Entry<String, List<String>> entry : headers.entrySet()) {
55+
if (isHeaderAllowed(entry.getKey())) {
56+
List<String> values = entry.getValue();
5457
for (int i = 0; i < values.size(); i++) {
5558
if (i == 0) {
56-
request.setHeader(entry.getKey().toString(), values.get(i));
59+
request.setHeader(entry.getKey(), values.get(i));
5760
} else {
58-
request.addHeader(entry.getKey().toString(), values.get(i));
61+
request.addHeader(entry.getKey(), values.get(i));
5962
}
6063
}
6164
}
6265
}
6366
} catch (Exception e) {
64-
throw new IllegalArgumentException(String.format("Problem adding custom headers to request decorator: %s", e), e);
67+
throw new IllegalArgumentException(
68+
String.format("Problem adding custom headers to request decorator: %s", e), e);
6569
}
6670

6771
return request;
@@ -70,9 +74,10 @@ public HttpUriRequestBase decorateHeaders(HttpUriRequestBase request) {
7074
private boolean isHeaderAllowed(String headerName) {
7175
return !forbiddenHeaders.contains(headerName.toLowerCase());
7276
}
77+
7378
private Map<String, List<String>> convertToMap(Header[] to_convert) {
7479
Map<String, List<String>> to_return = new HashMap<String, List<String>>();
75-
for (Integer i = 0; i < to_convert.length; i++ ) {
80+
for (Integer i = 0; i < to_convert.length; i++) {
7681
if (!to_return.containsKey(to_convert[i].getName())) {
7782
to_return.put(to_convert[i].getName(), new ArrayList<String>());
7883
}

client/src/main/java/io/split/client/SplitFactoryImpl.java

Lines changed: 121 additions & 82 deletions
Large diffs are not rendered by default.

client/src/main/java/io/split/client/impressions/HttpImpressionsSender.java

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.io.IOException;
2020
import java.net.URI;
2121
import java.net.URISyntaxException;
22+
import java.util.Collections;
2223
import java.util.HashMap;
2324
import java.util.List;
2425
import java.util.Map;
@@ -42,17 +43,19 @@ public class HttpImpressionsSender implements ImpressionsSender {
4243
private final ImpressionsManager.Mode _mode;
4344
private final TelemetryRuntimeProducer _telemetryRuntimeProducer;
4445

45-
public static HttpImpressionsSender create(SplitHttpClient client, URI eventsRootEndpoint, ImpressionsManager.Mode mode,
46-
TelemetryRuntimeProducer telemetryRuntimeProducer) throws URISyntaxException {
46+
public static HttpImpressionsSender create(SplitHttpClient client, URI eventsRootEndpoint,
47+
ImpressionsManager.Mode mode,
48+
TelemetryRuntimeProducer telemetryRuntimeProducer) throws URISyntaxException {
4749
return new HttpImpressionsSender(client,
4850
Utils.appendPath(eventsRootEndpoint, BULK_ENDPOINT_PATH),
4951
Utils.appendPath(eventsRootEndpoint, COUNT_ENDPOINT_PATH),
5052
mode,
5153
telemetryRuntimeProducer);
5254
}
5355

54-
private HttpImpressionsSender(SplitHttpClient client, URI impressionBulkTarget, URI impressionCountTarget, ImpressionsManager.Mode mode,
55-
TelemetryRuntimeProducer telemetryRuntimeProducer) {
56+
private HttpImpressionsSender(SplitHttpClient client, URI impressionBulkTarget, URI impressionCountTarget,
57+
ImpressionsManager.Mode mode,
58+
TelemetryRuntimeProducer telemetryRuntimeProducer) {
5659
_client = client;
5760
_mode = mode;
5861
_impressionBulkTarget = impressionBulkTarget;
@@ -65,19 +68,21 @@ public void postImpressionsBulk(List<TestImpressions> impressions) {
6568
long initTime = System.currentTimeMillis();
6669
try {
6770
HttpEntity entity = Utils.toJsonEntity(impressions);
68-
Map<String, String> additionalHeader = new HashMap<>();
69-
additionalHeader.put(IMPRESSIONS_MODE_HEADER, _mode.toString());
70-
SplitHttpResponse response = _client.post(_impressionBulkTarget, entity, additionalHeader);
71+
Map<String, List<String>> additionalHeaders = Collections.singletonMap(IMPRESSIONS_MODE_HEADER,
72+
Collections.singletonList(_mode.toString()));
73+
SplitHttpResponse response = _client.post(_impressionBulkTarget, entity, additionalHeaders);
7174

7275
if (response.statusCode() < HttpStatus.SC_OK || response.statusCode() >= HttpStatus.SC_MULTIPLE_CHOICES) {
7376
_telemetryRuntimeProducer.recordSyncError(ResourceEnum.IMPRESSION_SYNC, response.statusCode());
7477
}
75-
_telemetryRuntimeProducer.recordSuccessfulSync(LastSynchronizationRecordsEnum.IMPRESSIONS, System.currentTimeMillis());
78+
_telemetryRuntimeProducer.recordSuccessfulSync(LastSynchronizationRecordsEnum.IMPRESSIONS,
79+
System.currentTimeMillis());
7680

7781
} catch (Throwable t) {
7882
_logger.warn("Exception when posting impressions" + impressions, t);
7983
} finally {
80-
_telemetryRuntimeProducer.recordSyncLatency(HTTPLatenciesEnum.IMPRESSIONS, System.currentTimeMillis() - initTime);
84+
_telemetryRuntimeProducer.recordSyncLatency(HTTPLatenciesEnum.IMPRESSIONS,
85+
System.currentTimeMillis() - initTime);
8186
}
8287
}
8388

@@ -91,14 +96,16 @@ public void postCounters(HashMap<ImpressionCounter.Key, Integer> raw) {
9196

9297
try {
9398
SplitHttpResponse response = _client.post(_impressionCountTarget,
94-
Utils.toJsonEntity(ImpressionCount.fromImpressionCounterData(raw)),
95-
null);
99+
Utils.toJsonEntity(ImpressionCount.fromImpressionCounterData(raw)),
100+
null);
96101

97102
if (response.statusCode() < HttpStatus.SC_OK || response.statusCode() >= HttpStatus.SC_MULTIPLE_CHOICES) {
98103
_telemetryRuntimeProducer.recordSyncError(ResourceEnum.IMPRESSION_COUNT_SYNC, response.statusCode());
99104
}
100-
_telemetryRuntimeProducer.recordSyncLatency(HTTPLatenciesEnum.IMPRESSIONS_COUNT, System.currentTimeMillis() - initTime);
101-
_telemetryRuntimeProducer.recordSuccessfulSync(LastSynchronizationRecordsEnum.IMPRESSIONS_COUNT, System.currentTimeMillis());
105+
_telemetryRuntimeProducer.recordSyncLatency(HTTPLatenciesEnum.IMPRESSIONS_COUNT,
106+
System.currentTimeMillis() - initTime);
107+
_telemetryRuntimeProducer.recordSuccessfulSync(LastSynchronizationRecordsEnum.IMPRESSIONS_COUNT,
108+
System.currentTimeMillis());
102109
} catch (IOException exc) {
103110
_logger.warn("Exception when posting impression counters: ", exc);
104111
}
Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,33 @@
11
package io.split.service;
22

33
import io.split.engine.common.FetchOptions;
4-
import io.split.telemetry.domain.enums.HttpParamsWrapper;
54
import io.split.client.dtos.SplitHttpResponse;
65

76
import org.apache.hc.core5.http.HttpEntity;
87
import java.io.IOException;
98
import java.net.URI;
9+
import java.util.List;
1010
import java.util.Map;
1111

1212
public interface SplitHttpClient {
1313
/**
1414
* Wrapper for HTTP get method
15-
* @param uri the URL to be used
15+
*
16+
* @param uri the URL to be used
1617
* @param options The FetchOptions object that contains headers.
1718
* @return The response structure SplitHttpResponse
1819
*/
19-
public SplitHttpResponse get(URI uri, FetchOptions options, Map<String, String> additionalHeaders);
20+
public SplitHttpResponse get(URI uri, FetchOptions options, Map<String, List<String>> additionalHeaders);
21+
2022
/**
2123
* Wrapper for HTTP post method
22-
* @param uri the URL to be used
23-
* @param entity HttpEntity object that has The body load
24+
*
25+
* @param uri the URL to be used
26+
* @param entity HttpEntity object that has The body load
2427
* @param additionalHeaders Any additional headers to be added.
2528
* @return The response structure SplitHttpResponse
2629
*/
27-
public SplitHttpResponse post
28-
(URI uri,
29-
HttpEntity entity,
30-
Map<String, String> additionalHeaders) throws IOException;
30+
public SplitHttpResponse post(URI uri,
31+
HttpEntity entity,
32+
Map<String, List<String>> additionalHeaders) throws IOException;
3133
}
Lines changed: 59 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.split.service;
22

33
import io.split.client.RequestDecorator;
4+
import io.split.client.utils.SDKMetadata;
45
import io.split.client.utils.Utils;
56
import io.split.engine.common.FetchOptions;
67
import io.split.client.dtos.SplitHttpResponse;
@@ -16,77 +17,99 @@
1617
import java.io.IOException;
1718
import java.net.URI;
1819
import java.net.URISyntaxException;
20+
import org.apache.hc.core5.http.HttpRequest;
1921
import java.nio.charset.StandardCharsets;
22+
import java.util.List;
2023
import java.util.Map;
2124

2225
public final class SplitHttpClientImpl implements SplitHttpClient {
26+
2327
private static final Logger _log = LoggerFactory.getLogger(SplitHttpClient.class);
2428
private static final String HEADER_CACHE_CONTROL_NAME = "Cache-Control";
2529
private static final String HEADER_CACHE_CONTROL_VALUE = "no-cache";
30+
private static final String HEADER_API_KEY = "Authorization";
31+
private static final String HEADER_CLIENT_KEY = "SplitSDKClientKey";
32+
private static final String HEADER_CLIENT_MACHINE_NAME = "SplitSDKMachineName";
33+
private static final String HEADER_CLIENT_MACHINE_IP = "SplitSDKMachineIP";
34+
private static final String HEADER_CLIENT_VERSION = "SplitSDKVersion";
35+
2636
private final CloseableHttpClient _client;
2737
private final RequestDecorator _requestDecorator;
38+
private final String _apikey;
39+
private final SDKMetadata _metadata;
2840

29-
public static SplitHttpClientImpl create(
30-
CloseableHttpClient client,
31-
RequestDecorator requestDecorator
32-
) throws URISyntaxException {
33-
return new SplitHttpClientImpl(client, requestDecorator);
41+
public static SplitHttpClientImpl create(CloseableHttpClient client,
42+
RequestDecorator requestDecorator,
43+
String apikey,
44+
SDKMetadata metadata) throws URISyntaxException {
45+
return new SplitHttpClientImpl(client, requestDecorator, apikey, metadata);
3446
}
3547

36-
private SplitHttpClientImpl
37-
(CloseableHttpClient client,
38-
RequestDecorator requestDecorator) {
48+
private SplitHttpClientImpl(CloseableHttpClient client,
49+
RequestDecorator requestDecorator,
50+
String apikey,
51+
SDKMetadata metadata) {
3952
_client = client;
4053
_requestDecorator = requestDecorator;
54+
_apikey = apikey;
55+
_metadata = metadata;
4156
}
4257

43-
public SplitHttpResponse get(URI uri, FetchOptions options, Map<String, String> additionalHeaders) {
58+
public SplitHttpResponse get(URI uri, FetchOptions options, Map<String, List<String>> additionalHeaders) {
4459
CloseableHttpResponse response = null;
4560

4661
try {
4762
HttpGet request = new HttpGet(uri);
63+
setBasicHeaders(request);
4864
if (additionalHeaders != null) {
49-
for (Map.Entry entry : additionalHeaders.entrySet()) {
50-
request.addHeader(entry.getKey().toString(), entry.getValue());
65+
for (Map.Entry<String, List<String>> entry : additionalHeaders.entrySet()) {
66+
for (String value : entry.getValue()) {
67+
request.addHeader(entry.getKey(), value);
68+
}
5169
}
5270
}
53-
if(options.cacheControlHeadersEnabled()) {
71+
if (options.cacheControlHeadersEnabled()) {
5472
request.setHeader(HEADER_CACHE_CONTROL_NAME, HEADER_CACHE_CONTROL_VALUE);
5573
}
56-
request = (HttpGet) _requestDecorator.decorateHeaders(request);
74+
75+
_requestDecorator.decorateHeaders(request);
5776

5877
response = _client.execute(request);
5978

6079
if (_log.isDebugEnabled()) {
61-
_log.debug(String.format("[%s] %s. Status code: %s", request.getMethod(), uri.toURL(), response.getCode()));
80+
_log.debug(String.format("[%s] %s. Status code: %s", request.getMethod(), uri.toURL(),
81+
response.getCode()));
6282
}
6383

6484
String statusMessage = "";
6585
if (response.getCode() < HttpStatus.SC_OK || response.getCode() >= HttpStatus.SC_MULTIPLE_CHOICES) {
66-
_log.warn(String.format("Response status was: %s. Reason: %s", response.getCode() , response.getReasonPhrase()));
86+
_log.warn(String.format("Response status was: %s. Reason: %s", response.getCode(),
87+
response.getReasonPhrase()));
6788
statusMessage = response.getReasonPhrase();
6889
}
6990
return new SplitHttpResponse(response.getCode(),
70-
statusMessage,
71-
EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8),
72-
response.getHeaders());
91+
statusMessage,
92+
EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8),
93+
response.getHeaders());
7394
} catch (Exception e) {
7495
throw new IllegalStateException(String.format("Problem in http get operation: %s", e), e);
7596
} finally {
7697
Utils.forceClose(response);
7798
}
7899
}
79100

80-
public SplitHttpResponse post
81-
(URI uri,
82-
HttpEntity entity,
83-
Map<String, String> additionalHeaders) throws IOException {
101+
public SplitHttpResponse post(URI uri, HttpEntity entity, Map<String, List<String>> additionalHeaders)
102+
throws IOException {
103+
84104
CloseableHttpResponse response = null;
85105
try {
86106
HttpPost request = new HttpPost(uri);
107+
setBasicHeaders(request);
87108
if (additionalHeaders != null) {
88-
for (Map.Entry entry : additionalHeaders.entrySet()) {
89-
request.addHeader(entry.getKey().toString(), entry.getValue());
109+
for (Map.Entry<String, List<String>> entry : additionalHeaders.entrySet()) {
110+
for (String value : entry.getValue()) {
111+
request.addHeader(entry.getKey(), value);
112+
}
90113
}
91114
}
92115
request.setEntity(entity);
@@ -97,7 +120,8 @@ public SplitHttpResponse get(URI uri, FetchOptions options, Map<String, String>
97120
String statusMessage = "";
98121
if (response.getCode() < HttpStatus.SC_OK || response.getCode() >= HttpStatus.SC_MULTIPLE_CHOICES) {
99122
statusMessage = response.getReasonPhrase();
100-
_log.warn(String.format("Response status was: %s. Reason: %s", response.getCode(), response.getReasonPhrase()));
123+
_log.warn(String.format("Response status was: %s. Reason: %s", response.getCode(),
124+
response.getReasonPhrase()));
101125
}
102126
return new SplitHttpResponse(response.getCode(), statusMessage, "", response.getHeaders());
103127
} catch (Exception e) {
@@ -106,4 +130,14 @@ public SplitHttpResponse get(URI uri, FetchOptions options, Map<String, String>
106130
Utils.forceClose(response);
107131
}
108132
}
133+
134+
private void setBasicHeaders(HttpRequest request) {
135+
request.setHeader(HEADER_API_KEY, "Bearer " + _apikey);
136+
request.setHeader(HEADER_CLIENT_VERSION, _metadata.getSdkVersion());
137+
request.setHeader(HEADER_CLIENT_MACHINE_IP, _metadata.getMachineIp());
138+
request.setHeader(HEADER_CLIENT_MACHINE_NAME, _metadata.getMachineName());
139+
request.setHeader(HEADER_CLIENT_KEY, _apikey.length() > 4
140+
? _apikey.substring(_apikey.length() - 4)
141+
: _apikey);
142+
}
109143
}

0 commit comments

Comments
 (0)