Fix Content-Length handling using Netty.

VaultClient now uses a ClientHttpRequestInterceptor to force marshaling. Outgoing data is buffered and available as byte array. This allows setting a Content-Length header using netty. Previously, requests were streamed to the TCP channel without knowing the request body size in advance. Vault expects a Content-Length header and rejected requests with a body but without a Content-Length header.

Fixes gh-19.
This commit is contained in:
Mark Paluch
2016-09-24 11:18:39 +02:00
parent 90b8f15860
commit 4cbd08ec94
3 changed files with 25 additions and 10 deletions

View File

@@ -34,8 +34,8 @@
</dependency>
<dependency>
<groupId>com.squareup.okhttp</groupId>
<artifactId>okhttp</artifactId>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<scope>test</scope>
</dependency>

View File

@@ -159,8 +159,10 @@ public class VaultBootstrapConfiguration {
catch (ClassNotFoundException ex) {
switch (appId.getUserId().toUpperCase()) {
case VaultProperties.AppIdProperties.IP_ADDRESS:
return new IpAddressUserId();
case VaultProperties.AppIdProperties.MAC_ADDRESS:
if (StringUtils.hasText(appId.getNetworkInterface())) {
@@ -248,15 +250,12 @@ public class VaultBootstrapConfiguration {
@ConditionalOnMissingBean
public VaultClient vaultClient() {
RestTemplate restTemplate = new RestTemplate(
clientHttpRequestFactoryWrapper().getClientHttpRequestFactory());
VaultEndpoint vaultEndpoint = new VaultEndpoint();
vaultEndpoint.setHost(vaultProperties.getHost());
vaultEndpoint.setPort(vaultProperties.getPort());
vaultEndpoint.setScheme(vaultProperties.getScheme());
return new VaultClient(restTemplate, vaultEndpoint);
return new VaultClient(clientHttpRequestFactoryWrapper().getClientHttpRequestFactory(), vaultEndpoint);
}
/**

View File

@@ -16,11 +16,16 @@
package org.springframework.cloud.vault.util;
import java.io.IOException;
import java.util.concurrent.atomic.AtomicReference;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.util.Assert;
import org.springframework.vault.config.ClientHttpRequestFactoryFactory;
import org.springframework.vault.support.ClientOptions;
@@ -75,11 +80,22 @@ public class TestRestTemplateFactory {
Assert.notNull(requestFactory, "ClientHttpRequestFactory must not be null!");
RestTemplate RestTemplate = new RestTemplate();
RestTemplate.setErrorHandler(new DefaultResponseErrorHandler());
RestTemplate.setRequestFactory(requestFactory);
RestTemplate restTemplate = new RestTemplate();
restTemplate.setErrorHandler(new DefaultResponseErrorHandler());
restTemplate.setRequestFactory(requestFactory);
return RestTemplate;
restTemplate.getInterceptors().add(new ClientHttpRequestInterceptor() {
@Override
public ClientHttpResponse intercept(HttpRequest httpRequest, byte[] bytes,
ClientHttpRequestExecution clientHttpRequestExecution)
throws IOException {
return clientHttpRequestExecution.execute(httpRequest, bytes);
}
});
return restTemplate;
}
private static void initializeClientHttpRequestFactory(