feat(APIMAN-1230) Keep Content-Length when no mutating policies in the pipeline.
Resolves
MODIFY
gateway/engine/core/src/main/java/io/apiman/gateway/engine/IConnectorFactory.java
gateway/engine/core/src/main/java/io/apiman/gateway/engine/IConnectorFactory.java
@@ -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);
}

MODIFY
gateway/engine/core/src/main/java/io/apiman/gateway/engine/impl/ApiRequestExecutorImpl.java
gateway/engine/core/src/main/java/io/apiman/gateway/engine/impl/ApiRequestExecutorImpl.java
@@ -52,6 +52,7 @@ import io.apiman.gateway.engine.io.XmlPayloadIO;
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;
@@ -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}.
@@ -241,7 +243,7 @@ public class ApiRequestExecutorImpl implements IApiRequestExecutor {
IApiConnector connector;
if (connectorInterceptor == null) {
connector = connectorFactory.createConnector(req, api,
- RequiredAuthType.parseType(api));
+ RequiredAuthType.parseType(api), hasDataPolicy);
} else {
connector = connectorInterceptor.createConnector();
}
@@ -603,6 +605,10 @@ public class ApiRequestExecutorImpl implements IApiRequestExecutor {
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);

MODIFY
gateway/engine/core/src/test/java/io/apiman/gateway/engine/impl/DefaultEngineFactoryTest.java
gateway/engine/core/src/test/java/io/apiman/gateway/engine/impl/DefaultEngineFactoryTest.java
@@ -113,7 +113,7 @@ public class DefaultEngineFactoryTest {
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() {

MODIFY
gateway/platforms/servlet/src/main/java/io/apiman/gateway/platforms/servlet/connectors/HttpApiConnection.java
gateway/platforms/servlet/src/main/java/io/apiman/gateway/platforms/servlet/connectors/HttpApiConnection.java
@@ -38,11 +38,11 @@ import java.io.OutputStream;
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;
@@ -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$
@@ -99,6 +97,8 @@ public class HttpApiConnection implements IApiConnection, IApiConnectionResponse
private ApiResponse response;
final private OkHttpClient client;
+ private boolean hasDataPolicy;
+
/**
* Constructor.
*
@@ -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 {
@@ -178,6 +180,10 @@ public class HttpApiConnection implements IApiConnection, IApiConnectionResponse
}
}
+ if (hasDataPolicy) {
+ suppressedHeaders.add("Content-Length"); //$NON-NLS-1$
+ }
+
if (isSsl) {
HttpsURLConnection https = (HttpsURLConnection) connection;
SSLSocketFactory socketFactory = sslStrategy.getSocketFactory();

MODIFY
gateway/platforms/servlet/src/main/java/io/apiman/gateway/platforms/servlet/connectors/HttpConnectorFactory.java
gateway/platforms/servlet/src/main/java/io/apiman/gateway/platforms/servlet/connectors/HttpConnectorFactory.java
@@ -104,7 +104,7 @@ public class HttpConnectorFactory implements IConnectorFactory {
*/
@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)
@@ -114,7 +114,7 @@ public class HttpConnectorFactory implements IConnectorFactory {
IAsyncResultHandler<IApiConnectionResponse> handler) throws ConnectorException {
HttpApiConnection connection = new HttpApiConnection(okClient, request, api,
- requiredAuthType, getSslStrategy(requiredAuthType), handler);
+ requiredAuthType, getSslStrategy(requiredAuthType), hasDataPolicy, handler);
return connection;
}
};

MODIFY
gateway/platforms/servlet/src/test/java/io/apiman/gateway/platforms/servlet/auth/basic/BasicAuthTest.java
gateway/platforms/servlet/src/test/java/io/apiman/gateway/platforms/servlet/auth/basic/BasicAuthTest.java
@@ -171,7 +171,7 @@ public class BasicAuthTest {
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
@@ -199,7 +199,7 @@ public class BasicAuthTest {
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
@@ -227,7 +227,7 @@ public class BasicAuthTest {
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
@@ -255,7 +255,7 @@ public class BasicAuthTest {
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
@@ -283,7 +283,7 @@ public class BasicAuthTest {
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

MODIFY
gateway/platforms/servlet/src/test/java/io/apiman/gateway/platforms/servlet/auth/tls/BasicMutualAuthTest.java
gateway/platforms/servlet/src/test/java/io/apiman/gateway/platforms/servlet/auth/tls/BasicMutualAuthTest.java
@@ -178,7 +178,7 @@ public class BasicMutualAuthTest {
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>() {
@@ -211,7 +211,7 @@ public class BasicMutualAuthTest {
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>() {
@@ -247,7 +247,7 @@ public class BasicMutualAuthTest {
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>() {
@@ -283,7 +283,7 @@ public class BasicMutualAuthTest {
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>() {
@@ -321,7 +321,7 @@ public class BasicMutualAuthTest {
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>() {
@@ -365,7 +365,7 @@ public class BasicMutualAuthTest {
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>() {
@@ -404,7 +404,7 @@ public class BasicMutualAuthTest {
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>() {
@@ -428,7 +428,7 @@ public class BasicMutualAuthTest {
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>() {

MODIFY
gateway/platforms/servlet/src/test/java/io/apiman/gateway/platforms/servlet/auth/tls/CAMutualAuthTest.java
gateway/platforms/servlet/src/test/java/io/apiman/gateway/platforms/servlet/auth/tls/CAMutualAuthTest.java
@@ -157,7 +157,7 @@ public class CAMutualAuthTest {
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>() {
@@ -191,7 +191,7 @@ public class CAMutualAuthTest {
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>() {

MODIFY
gateway/platforms/servlet/src/test/java/io/apiman/gateway/platforms/servlet/auth/tls/CipherAndProtocolSelectionTest.java
gateway/platforms/servlet/src/test/java/io/apiman/gateway/platforms/servlet/auth/tls/CipherAndProtocolSelectionTest.java
@@ -166,7 +166,7 @@ public class CipherAndProtocolSelectionTest {
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>() {
@@ -204,7 +204,7 @@ public class CipherAndProtocolSelectionTest {
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>() {
@@ -239,7 +239,7 @@ public class CipherAndProtocolSelectionTest {
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>() {
@@ -274,7 +274,7 @@ public class CipherAndProtocolSelectionTest {
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>() {
@@ -309,7 +309,7 @@ public class CipherAndProtocolSelectionTest {
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>() {
@@ -345,7 +345,7 @@ public class CipherAndProtocolSelectionTest {
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>() {
@@ -382,7 +382,7 @@ public class CipherAndProtocolSelectionTest {
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>() {

MODIFY
gateway/platforms/servlet/src/test/java/io/apiman/gateway/platforms/servlet/auth/tls/StandardTLSTest.java
gateway/platforms/servlet/src/test/java/io/apiman/gateway/platforms/servlet/auth/tls/StandardTLSTest.java
@@ -156,7 +156,7 @@ public class StandardTLSTest {
config.put(TLSOptions.TLS_ALLOWSELFSIGNED, "false");
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>() {
@@ -187,7 +187,7 @@ public class StandardTLSTest {
config.put(TLSOptions.TLS_ALLOWSELFSIGNED, "false");
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>() {
@@ -212,7 +212,7 @@ public class StandardTLSTest {
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>() {
@@ -234,7 +234,7 @@ public class StandardTLSTest {
@Test
public void shouldFailWithNoSettings() {
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>() {

MODIFY
gateway/platforms/vertx3/vertx3/src/main/java/io/apiman/gateway/platforms/vertx3/connector/ConnectorFactory.java
gateway/platforms/vertx3/vertx3/src/main/java/io/apiman/gateway/platforms/vertx3/connector/ConnectorFactory.java
@@ -41,7 +41,6 @@ public class ConnectorFactory implements IConnectorFactory {
private static final Set<String> SUPPRESSED_HEADERS = new HashSet<>();
static {
SUPPRESSED_HEADERS.add("Transfer-Encoding"); //$NON-NLS-1$
- SUPPRESSED_HEADERS.add("Content-Length"); //$NON-NLS-1$
SUPPRESSED_HEADERS.add("X-API-Key"); //$NON-NLS-1$
}
@@ -59,7 +58,7 @@ public class ConnectorFactory implements IConnectorFactory {
}
@Override
- public IApiConnector createConnector(ApiRequest request, final Api api, RequiredAuthType authType) {
+ public IApiConnector createConnector(ApiRequest request, final Api api, RequiredAuthType authType, boolean hasDataPolicy) {
return new IApiConnector() {
@Override
@@ -67,7 +66,7 @@ public class ConnectorFactory implements IConnectorFactory {
IAsyncResultHandler<IApiConnectionResponse> resultHandler)
throws ConnectorException {
// In the future we can switch to different back-end implementations here!
- return new HttpConnector(vertx, api, request, authType, tlsOptions, resultHandler);
+ return new HttpConnector(vertx, api, request, authType, tlsOptions, hasDataPolicy, resultHandler);
}
};
}

MODIFY
gateway/platforms/vertx3/vertx3/src/main/java/io/apiman/gateway/platforms/vertx3/connector/HttpConnector.java
gateway/platforms/vertx3/vertx3/src/main/java/io/apiman/gateway/platforms/vertx3/connector/HttpConnector.java
@@ -71,7 +71,6 @@ class HttpConnector implements IApiConnectionResponse, IApiConnection {
private static final Set<String> SUPPRESSED_HEADERS = new HashSet<>();
static {
SUPPRESSED_HEADERS.add("Transfer-Encoding");
- SUPPRESSED_HEADERS.add("Content-Length");
SUPPRESSED_HEADERS.add("X-API-Key");
SUPPRESSED_HEADERS.add("Host");
}
@@ -104,6 +103,8 @@ class HttpConnector implements IApiConnectionResponse, IApiConnection {
private URL apiEndpoint;
+ private boolean hasDataPolicies;
+
/**
* Construct an {@link HttpConnector} instance. The {@link #resultHandler} must remain exclusive to a
* given instance.
@@ -113,15 +114,17 @@ class HttpConnector implements IApiConnectionResponse, IApiConnection {
* @param request a request with fields filled
* @param authType the required auth type
* @param tlsOptions the tls options
+ * @param hasDataPolicy if the policy chain contains a data policy
* @param resultHandler a handler, called when reading is permitted
*/
public HttpConnector(Vertx vertx, Api api, ApiRequest request, RequiredAuthType authType,
- TLSOptions tlsOptions, IAsyncResultHandler<IApiConnectionResponse> resultHandler) {
+ TLSOptions tlsOptions, boolean hasDataPolicy, IAsyncResultHandler<IApiConnectionResponse> resultHandler) {
this.api = api;
this.apiRequest = request;
this.authType = authType;
this.resultHandler = resultHandler;
this.exceptionHandler = new ExceptionHandler();
+ this.hasDataPolicies = hasDataPolicy;
apiEndpoint = parseApiEndpoint(api);
@@ -197,7 +200,12 @@ class HttpConnector implements IApiConnectionResponse, IApiConnection {
});
clientRequest.exceptionHandler(exceptionHandler);
+
+ if (hasDataPolicies) {
+ clientRequest.headers().remove("Content-Length");
clientRequest.setChunked(true);
+ }
+
apiRequest.getHeaders().forEach(e -> clientRequest.headers().add(e.getKey(), e.getValue()));
addMandatoryRequestHeaders(clientRequest.headers());

MODIFY
gateway/platforms/vertx3/vertx3/src/main/java/io/apiman/gateway/platforms/vertx3/http/HttpPolicyAdapter.java
gateway/platforms/vertx3/vertx3/src/main/java/io/apiman/gateway/platforms/vertx3/http/HttpPolicyAdapter.java
@@ -65,7 +65,7 @@ public class HttpPolicyAdapter {
// Exception
vertxRequest.exceptionHandler(ex -> {
handleError(vertxResponse, ex);
- }); // TODO: handle here or level above?
+ }); // TODO: Should probably log error also.
// Set up executor to run conversation through apiman's policy engine.
IApiRequestExecutor executor = engine.executor(request, result -> {
@@ -98,7 +98,10 @@ public class HttpPolicyAdapter {
if (engineResult.isResponse()) {
ApiResponse response = engineResult.getApiResponse();
HttpApiFactory.buildResponse(vertxResponse, response, vertxRequest.version());
+
+ if (!response.getHeaders().containsKey("Content-Length")) { //$NON-NLS-1$
vertxResponse.setChunked(true);
+ }
engineResult.bodyHandler(buffer -> {
vertxResponse.write((Buffer) buffer.getNativeBuffer());
@@ -106,7 +109,7 @@ public class HttpPolicyAdapter {
engineResult.endHandler(end -> vertxResponse.end());
} else { // Policy failure (i.e. denial - it's not an exception).
- log.debug(String.format("Failed with policy failure (denial): %s", engineResult.getPolicyFailure()));
+ log.debug(String.format("Failed with policy failure (denial): %s", engineResult.getPolicyFailure())); //$NON-NLS-1$
handlePolicyFailure(vertxResponse, engineResult.getPolicyFailure());
}
}
@@ -155,7 +158,7 @@ public class HttpPolicyAdapter {
for (Map.Entry<String, String> entry : failure.getHeaders()) {
response.headers().add(entry.getKey(), entry.getValue());
}
-
+ response.setChunked(true);
response.end(Json.encode(failure));
}
}

MODIFY
pom.xml
pom.xml
<version.org.osgi>4.2.0</version.org.osgi>
<version.org.picketbox>4.9.6.Final</version.org.picketbox>
<version.org.slf4j>1.7.7</version.org.slf4j>
- <version.io.netty>4.1.4.Final</version.io.netty>
+ <version.io.netty>4.1.6.Final</version.io.netty>
<version.io.swagger>1.5.7</version.io.swagger>
<version.xmlunit>1.6</version.xmlunit>
<version.io.vertx>3.3.2</version.io.vertx>

MODIFY
test/policies/src/main/java/io/apiman/test/policies/PolicyTesterConnectorFactory.java
test/policies/src/main/java/io/apiman/test/policies/PolicyTesterConnectorFactory.java
@@ -32,7 +32,7 @@ public class PolicyTesterConnectorFactory implements IConnectorFactory {
* @see io.apiman.gateway.engine.IConnectorFactory#createConnector(io.apiman.gateway.engine.beans.ApiRequest, io.apiman.gateway.engine.beans.Api)
*/
@Override
- public IApiConnector createConnector(ApiRequest request, Api api, RequiredAuthType authType) {
+ public IApiConnector createConnector(ApiRequest request, Api api, RequiredAuthType authType, boolean hasDataPolicy) {
return new PolicyTesterConnector(api);
}

feat(APIMAN-1230) Keep Content-Length when no mutating policies in the pipeline.

Resolves APIMAN-1230