From 4cbd08ec94bfb9e1eb060a5443dd69cf7d843d5e Mon Sep 17 00:00:00 2001 From: Mark Paluch Date: Sat, 24 Sep 2016 11:18:39 +0200 Subject: [PATCH] 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. --- spring-cloud-vault-config-databases/pom.xml | 4 ++-- .../config/VaultBootstrapConfiguration.java | 7 +++--- .../vault/util/TestRestTemplateFactory.java | 24 +++++++++++++++---- 3 files changed, 25 insertions(+), 10 deletions(-) diff --git a/spring-cloud-vault-config-databases/pom.xml b/spring-cloud-vault-config-databases/pom.xml index 83820ae1..2d6ffe22 100644 --- a/spring-cloud-vault-config-databases/pom.xml +++ b/spring-cloud-vault-config-databases/pom.xml @@ -34,8 +34,8 @@ - com.squareup.okhttp - okhttp + io.netty + netty-all test diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultBootstrapConfiguration.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultBootstrapConfiguration.java index 31fac91c..813c26f9 100644 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultBootstrapConfiguration.java +++ b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultBootstrapConfiguration.java @@ -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); } /** diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/util/TestRestTemplateFactory.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/util/TestRestTemplateFactory.java index 23bcc17e..0904ce62 100644 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/util/TestRestTemplateFactory.java +++ b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/util/TestRestTemplateFactory.java @@ -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(