Skip to content

Commit

Permalink
feat(APIMAN-1230) Keep Content-Length when no mutating policies in th…
Browse files Browse the repository at this point in the history
…e pipeline.

Resolves APIMAN-1230
  • Loading branch information
msavy committed Jan 19, 2017
1 parent 9330a8c commit f694919
Show file tree
Hide file tree
Showing 15 changed files with 72 additions and 49 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ public interface IConnectorFactory {
* @param request the inbound API request
* @param api the managed API being invoked
* @param requiredAuthType the required authorization type
* @param hasDataPolicy if the policy chain contains a data policy
* @return a connector to the back-end API
*/
public IApiConnector createConnector(ApiRequest request, Api api,
RequiredAuthType requiredAuthType);
RequiredAuthType requiredAuthType, boolean hasDataPolicy);

}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@
import io.apiman.gateway.engine.metrics.RequestMetric;
import io.apiman.gateway.engine.policy.Chain;
import io.apiman.gateway.engine.policy.IConnectorInterceptor;
import io.apiman.gateway.engine.policy.IDataPolicy;
import io.apiman.gateway.engine.policy.IPolicy;
import io.apiman.gateway.engine.policy.IPolicyContext;
import io.apiman.gateway.engine.policy.IPolicyFactory;
Expand Down Expand Up @@ -128,6 +129,7 @@ public class ApiRequestExecutorImpl implements IApiRequestExecutor {
private IPayloadIO payloadIO;
// max payload buffer size (if not already set in the api itself)
private long maxPayloadBufferSize = DEFAULT_MAX_PAYLOAD_BUFFER_SIZE;
private boolean hasDataPolicy = false;

/**
* Constructs a new {@link ApiRequestExecutorImpl}.
Expand All @@ -141,7 +143,7 @@ public class ApiRequestExecutorImpl implements IApiRequestExecutor {
*/
public ApiRequestExecutorImpl(ApiRequest apiRequest,
IAsyncResultHandler<IEngineResult> resultHandler, IRegistry registry, IPolicyContext context,
IPolicyFactory policyFactory, IConnectorFactory connectorFactory, IMetrics metrics,
IPolicyFactory policyFactory, IConnectorFactory connectorFactory, IMetrics metrics,
IBufferFactoryComponent bufferFactory) {
this.request = apiRequest;
this.registry = registry;
Expand Down Expand Up @@ -241,7 +243,7 @@ public void execute() {
IApiConnector connector;
if (connectorInterceptor == null) {
connector = connectorFactory.createConnector(req, api,
RequiredAuthType.parseType(api));
RequiredAuthType.parseType(api), hasDataPolicy);
} else {
connector = connectorInterceptor.createConnector();
}
Expand Down Expand Up @@ -603,6 +605,10 @@ private void loadPolicies(final IAsyncHandler<List<PolicyWithConfiguration>> han
policyFactory.loadPolicy(policy.getPolicyImpl(), (IAsyncResult<IPolicy> result) -> {
if (result.isSuccess()) {
IPolicy policyImpl = result.getResult();
// Test whether pipeline contains any data policies. Connectors can use this for Content-Length pass-through.
if (policyImpl instanceof IDataPolicy) {
hasDataPolicy = true;
}
try {
Object policyConfig = policyFactory.loadConfig(policyImpl, policy.getPolicyImpl(), policy.getPolicyJsonConfig());
PolicyWithConfiguration pwc = new PolicyWithConfiguration(policyImpl, policyConfig);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ protected void registerBufferFactoryComponent() {
protected IConnectorFactory createConnectorFactory(IPluginRegistry pluginRegistry) {
return new IConnectorFactory() {
@Override
public IApiConnector createConnector(ApiRequest request, Api api, RequiredAuthType requiredAuthType) {
public IApiConnector createConnector(ApiRequest request, Api api, RequiredAuthType requiredAuthType, boolean hasDataPolicy) {
Assert.assertEquals("test", api.getEndpointType());
Assert.assertEquals("test:endpoint", api.getEndpoint());
IApiConnector connector = new IApiConnector() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLEncoder;
import java.util.Map;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.TreeSet;
import java.util.Map.Entry;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSocketFactory;
Expand Down Expand Up @@ -70,11 +70,9 @@ public class HttpApiConnection implements IApiConnection, IApiConnectionResponse

static {
SUPPRESSED_REQUEST_HEADERS.add("Transfer-Encoding"); //$NON-NLS-1$
SUPPRESSED_REQUEST_HEADERS.add("Content-Length"); //$NON-NLS-1$
SUPPRESSED_REQUEST_HEADERS.add("X-API-Key"); //$NON-NLS-1$
SUPPRESSED_REQUEST_HEADERS.add("Host"); //$NON-NLS-1$


SUPPRESSED_RESPONSE_HEADERS.add("OkHttp-Received-Millis"); //$NON-NLS-1$
SUPPRESSED_RESPONSE_HEADERS.add("OkHttp-Response-Source"); //$NON-NLS-1$
SUPPRESSED_RESPONSE_HEADERS.add("OkHttp-Selected-Protocol"); //$NON-NLS-1$
Expand All @@ -99,6 +97,8 @@ public class HttpApiConnection implements IApiConnection, IApiConnectionResponse
private ApiResponse response;
final private OkHttpClient client;

private boolean hasDataPolicy;

/**
* Constructor.
*
Expand All @@ -107,17 +107,19 @@ public class HttpApiConnection implements IApiConnection, IApiConnectionResponse
* @param request the request
* @param api the API
* @param requiredAuthType the authorization type
* @param hasDataPolicy if policy chain contains data policies
* @param handler the result handler
* @throws ConnectorException when unable to connect
*/
public HttpApiConnection(OkHttpClient client, ApiRequest request, Api api,
RequiredAuthType requiredAuthType, SSLSessionStrategy sslStrategy,
IAsyncResultHandler<IApiConnectionResponse> handler) throws ConnectorException {
boolean hasDataPolicy, IAsyncResultHandler<IApiConnectionResponse> handler) throws ConnectorException {
this.client = client;
this.request = request;
this.api = api;
this.requiredAuthType = requiredAuthType;
this.sslStrategy = sslStrategy;
this.hasDataPolicy = hasDataPolicy;
this.responseHandler = handler;

try {
Expand Down Expand Up @@ -178,6 +180,10 @@ private void connect() throws ConnectorException {
}
}

if (hasDataPolicy) {
suppressedHeaders.add("Content-Length"); //$NON-NLS-1$
}

if (isSsl) {
HttpsURLConnection https = (HttpsURLConnection) connection;
SSLSocketFactory socketFactory = sslStrategy.getSocketFactory();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ private OkHttpClient createHttpClient() {
*/
@Override
public IApiConnector createConnector(ApiRequest request, final Api api,
final RequiredAuthType requiredAuthType) {
final RequiredAuthType requiredAuthType, boolean hasDataPolicy) {
return new IApiConnector() {
/**
* @see io.apiman.gateway.engine.IApiConnector#connect(io.apiman.gateway.engine.beans.ApiRequest, io.apiman.gateway.engine.async.IAsyncResultHandler)
Expand All @@ -114,7 +114,7 @@ public IApiConnection connect(ApiRequest request,
IAsyncResultHandler<IApiConnectionResponse> handler) throws ConnectorException {

HttpApiConnection connection = new HttpApiConnection(okClient, request, api,
requiredAuthType, getSslStrategy(requiredAuthType), handler);
requiredAuthType, getSslStrategy(requiredAuthType), hasDataPolicy, handler);
return connection;
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ public void shouldSucceedWithBasicAuth() {
api.setEndpoint("http://localhost:8008/echo");

HttpConnectorFactory factory = new HttpConnectorFactory(globalConfig);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.BASIC);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.BASIC, false);
IApiConnection connection = connector.connect(request,
new IAsyncResultHandler<IApiConnectionResponse>() {
@Override
Expand Down Expand Up @@ -199,7 +199,7 @@ public void shouldSucceedWithBasicAuthAndSSL() {
api.setEndpoint("https://localhost:8009/echo");

HttpConnectorFactory factory = new HttpConnectorFactory(globalConfig);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.BASIC);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.BASIC, false);
IApiConnection connection = connector.connect(request,
new IAsyncResultHandler<IApiConnectionResponse>() {
@Override
Expand Down Expand Up @@ -227,7 +227,7 @@ public void shouldFailWithNoSSL() {
api.setEndpoint("http://localhost:8008/echo");

HttpConnectorFactory factory = new HttpConnectorFactory(globalConfig);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.BASIC);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.BASIC, false);
IApiConnection connection = connector.connect(request,
new IAsyncResultHandler<IApiConnectionResponse>() {
@Override
Expand Down Expand Up @@ -255,7 +255,7 @@ public void shouldFailWithBadCredentials() {
api.setEndpoint("http://localhost:8008/echo");

HttpConnectorFactory factory = new HttpConnectorFactory(globalConfig);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.BASIC);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.BASIC, false);
IApiConnection connection = connector.connect(request,
new IAsyncResultHandler<IApiConnectionResponse>() {
@Override
Expand Down Expand Up @@ -283,7 +283,7 @@ public void shouldFailWithNoCredentials() {
api.setEndpoint("http://localhost:8008/echo");

HttpConnectorFactory factory = new HttpConnectorFactory(globalConfig);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.BASIC);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.BASIC, false);
IApiConnection connection = connector.connect(request,
new IAsyncResultHandler<IApiConnectionResponse>() {
@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ public void shouldSucceedWithValidMTLS() {
config.put(TLSOptions.TLS_ALLOWSELFSIGNED, "false");

HttpConnectorFactory factory = new HttpConnectorFactory(config);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.MTLS);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.MTLS, false);
IApiConnection connection = connector.connect(request,
new IAsyncResultHandler<IApiConnectionResponse>() {

Expand Down Expand Up @@ -211,7 +211,7 @@ public void shouldFailWhenGatewayDoesNotTrustApi() {
config.put(TLSOptions.TLS_ALLOWSELFSIGNED, "false");

HttpConnectorFactory factory = new HttpConnectorFactory(config);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.MTLS);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.MTLS, false);
IApiConnection connection = connector.connect(request,
new IAsyncResultHandler<IApiConnectionResponse>() {

Expand Down Expand Up @@ -247,7 +247,7 @@ public void shouldFailWhenApiDoesNotTrustGateway() {
config.put(TLSOptions.TLS_ALLOWSELFSIGNED, "false");

HttpConnectorFactory factory = new HttpConnectorFactory(config);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.MTLS);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.MTLS, false);
IApiConnection connection = connector.connect(request,
new IAsyncResultHandler<IApiConnectionResponse>() {

Expand Down Expand Up @@ -283,7 +283,7 @@ public void shouldSucceedWhenAllowedSelfSigned() {
config.put(TLSOptions.TLS_ALLOWSELFSIGNED, "true");

HttpConnectorFactory factory = new HttpConnectorFactory(config);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.MTLS);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.MTLS, false);
IApiConnection connection = connector.connect(request,
new IAsyncResultHandler<IApiConnectionResponse>() {

Expand Down Expand Up @@ -321,7 +321,7 @@ public void shouldSucceedWhenValidKeyAlias() throws CertificateException, IOExce
inStream.close();

HttpConnectorFactory factory = new HttpConnectorFactory(config);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.MTLS);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.MTLS, false);
IApiConnection connection = connector.connect(request,
new IAsyncResultHandler<IApiConnectionResponse>() {

Expand Down Expand Up @@ -365,7 +365,7 @@ public void shouldFallbackWhenMultipleAliasesAvailable() throws CertificateExcep
inStream.close();

HttpConnectorFactory factory = new HttpConnectorFactory(config);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.MTLS);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.MTLS, false);
IApiConnection connection = connector.connect(request,
new IAsyncResultHandler<IApiConnectionResponse>() {

Expand Down Expand Up @@ -404,7 +404,7 @@ public void shouldFailWithInValidKeyAlias() throws CertificateException, IOExcep
config.put(TLSOptions.TLS_KEYALIASES, "xxx");

HttpConnectorFactory factory = new HttpConnectorFactory(config);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.MTLS);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.MTLS, false);
IApiConnection connection = connector.connect(request,
new IAsyncResultHandler<IApiConnectionResponse>() {

Expand All @@ -428,7 +428,7 @@ public void shouldFailWithDevModeAndNoClientKeys() {
config.put(TLSOptions.TLS_DEVMODE, "true");

HttpConnectorFactory factory = new HttpConnectorFactory(config);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.DEFAULT);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.DEFAULT, false);
IApiConnection connection = connector.connect(request,
new IAsyncResultHandler<IApiConnectionResponse>() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ public void shouldSucceedWithValidMTLS() {
config.put(TLSOptions.TLS_ALLOWSELFSIGNED, "false");

HttpConnectorFactory factory = new HttpConnectorFactory(config);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.MTLS);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.MTLS, false);
IApiConnection connection = connector.connect(request,
new IAsyncResultHandler<IApiConnectionResponse>() {

Expand Down Expand Up @@ -191,7 +191,7 @@ public void shouldFailWhenCANotTrusted() {
config.put(TLSOptions.TLS_ALLOWSELFSIGNED, "false");

HttpConnectorFactory factory = new HttpConnectorFactory(config);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.MTLS);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.MTLS, false);
IApiConnection connection = connector.connect(request,
new IAsyncResultHandler<IApiConnectionResponse>() {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ public void shouldNotUseDisallowedCipher() throws Exception {
server.start();

HttpConnectorFactory factory = new HttpConnectorFactory(config);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.DEFAULT);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.DEFAULT, false);
IApiConnection connection = connector.connect(request,
new IAsyncResultHandler<IApiConnectionResponse>() {

Expand Down Expand Up @@ -204,7 +204,7 @@ public void shouldFailWhenNoValidCipherAllowed() throws Exception {


HttpConnectorFactory factory = new HttpConnectorFactory(config);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.DEFAULT);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.DEFAULT, false);
IApiConnection connection = connector.connect(request,
new IAsyncResultHandler<IApiConnectionResponse>() {

Expand Down Expand Up @@ -239,7 +239,7 @@ public void shouldFailWhenNoValidProtocolAllowed() throws Exception {


HttpConnectorFactory factory = new HttpConnectorFactory(config);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.DEFAULT);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.DEFAULT, false);
IApiConnection connection = connector.connect(request,
new IAsyncResultHandler<IApiConnectionResponse>() {

Expand Down Expand Up @@ -274,7 +274,7 @@ public void shouldFailWhenAllAvailableProtocolsExcluded() throws Exception {


HttpConnectorFactory factory = new HttpConnectorFactory(config);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.DEFAULT);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.DEFAULT, false);
IApiConnection connection = connector.connect(request,
new IAsyncResultHandler<IApiConnectionResponse>() {

Expand Down Expand Up @@ -309,7 +309,7 @@ public void shouldFailWhenRemoteProtocolsAreExcluded() throws Exception {
server.start();

HttpConnectorFactory factory = new HttpConnectorFactory(config);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.DEFAULT);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.DEFAULT, false);
IApiConnection connection = connector.connect(request,
new IAsyncResultHandler<IApiConnectionResponse>() {

Expand Down Expand Up @@ -345,7 +345,7 @@ public void shouldFailWhenRemoteCiphersAreExcluded() throws Exception {
server.start();

HttpConnectorFactory factory = new HttpConnectorFactory(config);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.DEFAULT);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.DEFAULT, false);
IApiConnection connection = connector.connect(request,
new IAsyncResultHandler<IApiConnectionResponse>() {

Expand Down Expand Up @@ -382,7 +382,7 @@ private String getPrefferedCipher() throws Exception {
final CountDownLatch latch = new CountDownLatch(1);

HttpConnectorFactory factory = new HttpConnectorFactory(config);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.DEFAULT);
IApiConnector connector = factory.createConnector(request, api, RequiredAuthType.DEFAULT, false);
IApiConnection connection = connector.connect(request,
new IAsyncResultHandler<IApiConnectionResponse>() {

Expand Down

0 comments on commit f694919

Please sign in to comment.