From b0b097bddbe1cf383a2272551a0afeb2141e4856 Mon Sep 17 00:00:00 2001 From: spencergibb Date: Tue, 23 Nov 2021 16:41:18 -0500 Subject: [PATCH 1/4] Makes ProxyExchange.DEFAULT_SENSITIVE read only. Fixes gh-2413 --- .../org/springframework/cloud/gateway/mvc/ProxyExchange.java | 3 ++- .../springframework/cloud/gateway/webflux/ProxyExchange.java | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/spring-cloud-gateway-mvc/src/main/java/org/springframework/cloud/gateway/mvc/ProxyExchange.java b/spring-cloud-gateway-mvc/src/main/java/org/springframework/cloud/gateway/mvc/ProxyExchange.java index c98d6f04..f38f0e57 100644 --- a/spring-cloud-gateway-mvc/src/main/java/org/springframework/cloud/gateway/mvc/ProxyExchange.java +++ b/spring-cloud-gateway-mvc/src/main/java/org/springframework/cloud/gateway/mvc/ProxyExchange.java @@ -140,7 +140,8 @@ public class ProxyExchange { /** * Contains headers that are considered case-sensitive by default. */ - public static Set DEFAULT_SENSITIVE = new HashSet<>(Arrays.asList("cookie", "authorization")); + public static Set DEFAULT_SENSITIVE = Collections + .unmodifiableSet(new HashSet<>(Arrays.asList("cookie", "authorization"))); private URI uri; diff --git a/spring-cloud-gateway-webflux/src/main/java/org/springframework/cloud/gateway/webflux/ProxyExchange.java b/spring-cloud-gateway-webflux/src/main/java/org/springframework/cloud/gateway/webflux/ProxyExchange.java index 5044ffcb..f82f4e2e 100644 --- a/spring-cloud-gateway-webflux/src/main/java/org/springframework/cloud/gateway/webflux/ProxyExchange.java +++ b/spring-cloud-gateway-webflux/src/main/java/org/springframework/cloud/gateway/webflux/ProxyExchange.java @@ -20,6 +20,7 @@ import java.lang.reflect.Type; import java.net.URI; import java.net.URISyntaxException; import java.util.Arrays; +import java.util.Collections; import java.util.HashSet; import java.util.Set; import java.util.function.Function; @@ -113,7 +114,8 @@ public class ProxyExchange { /** * Contains headers that are considered case-sensitive by default. */ - public static Set DEFAULT_SENSITIVE = new HashSet<>(Arrays.asList("cookie", "authorization")); + public static Set DEFAULT_SENSITIVE = Collections + .unmodifiableSet(new HashSet<>(Arrays.asList("cookie", "authorization"))); private HttpMethod httpMethod; From 6dbfd936547c9648337ef07d32a011ffe5370f06 Mon Sep 17 00:00:00 2001 From: Manuel Date: Sun, 16 May 2021 23:16:37 +0200 Subject: [PATCH 2/4] Adds body support to get in mvc ProxyExchange. Fixes gh-2247 --- spring-cloud-gateway-mvc/pom.xml | 5 + .../cloud/gateway/mvc/ProxyExchange.java | 3 +- .../gateway/mvc/GetWithBodyRequestTest.java | 203 ++++++++++++++++++ .../mvc/ProductionConfigurationTests.java | 11 +- .../ProxyExchangeArgumentResolverTest.java | 7 +- .../AbstractBufferingClientHttpRequest.java | 48 +++++ ...thBodyRequestClientHttpRequestFactory.java | 123 +++++++++++ .../http/HttpComponentsClientHttpRequest.java | 93 ++++++++ .../HttpComponentsClientHttpResponse.java | 84 ++++++++ 9 files changed, 567 insertions(+), 10 deletions(-) create mode 100644 spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/GetWithBodyRequestTest.java create mode 100644 spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/http/AbstractBufferingClientHttpRequest.java create mode 100644 spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/http/GetWithBodyRequestClientHttpRequestFactory.java create mode 100644 spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/http/HttpComponentsClientHttpRequest.java create mode 100644 spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/http/HttpComponentsClientHttpResponse.java diff --git a/spring-cloud-gateway-mvc/pom.xml b/spring-cloud-gateway-mvc/pom.xml index faa4d43e..656bac74 100644 --- a/spring-cloud-gateway-mvc/pom.xml +++ b/spring-cloud-gateway-mvc/pom.xml @@ -40,6 +40,11 @@ spring-boot-starter-actuator test + + org.apache.httpcomponents + httpclient + test + org.springframework.boot spring-boot-configuration-processor diff --git a/spring-cloud-gateway-mvc/src/main/java/org/springframework/cloud/gateway/mvc/ProxyExchange.java b/spring-cloud-gateway-mvc/src/main/java/org/springframework/cloud/gateway/mvc/ProxyExchange.java index f38f0e57..31828ffe 100644 --- a/spring-cloud-gateway-mvc/src/main/java/org/springframework/cloud/gateway/mvc/ProxyExchange.java +++ b/spring-cloud-gateway-mvc/src/main/java/org/springframework/cloud/gateway/mvc/ProxyExchange.java @@ -277,7 +277,8 @@ public class ProxyExchange { } public ResponseEntity get() { - RequestEntity requestEntity = headers((BodyBuilder) RequestEntity.get(uri)).build(); + RequestEntity requestEntity = headers((BodyBuilder) RequestEntity.get(uri)) + .body(body()); return exchange(requestEntity); } diff --git a/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/GetWithBodyRequestTest.java b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/GetWithBodyRequestTest.java new file mode 100644 index 00000000..41d951e7 --- /dev/null +++ b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/GetWithBodyRequestTest.java @@ -0,0 +1,203 @@ +/* + * Copyright 2016-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.gateway.mvc; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.IOException; +import java.net.URI; +import java.util.Collections; + +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.web.client.TestRestTemplate; +import org.springframework.boot.web.client.RestTemplateBuilder; +import org.springframework.boot.web.server.LocalServerPort; +import org.springframework.cloud.gateway.mvc.GetWithBodyRequestTest.TestApplication.Foo; +import org.springframework.cloud.gateway.mvc.config.ProxyExchangeArgumentResolver; +import org.springframework.cloud.gateway.mvc.config.ProxyProperties; +import org.springframework.cloud.gateway.mvc.http.GetWithBodyRequestClientHttpRequestFactory; +import org.springframework.context.annotation.Bean; +import org.springframework.http.HttpEntity; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpMethod; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.http.client.ClientHttpResponse; +import org.springframework.http.converter.ByteArrayHttpMessageConverter; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.junit4.SpringRunner; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; +import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.client.DefaultResponseErrorHandler; +import org.springframework.web.client.RestTemplate; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +@RunWith(SpringRunner.class) +@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) +@ContextConfiguration(classes = GetWithBodyRequestTest.TestApplication.class) +public class GetWithBodyRequestTest { + + @Autowired + private TestRestTemplate rest; + + @Autowired + private TestApplication testApplication; + + @LocalServerPort + private int port; + + @Before + public void init() throws Exception { + testApplication.setHome(new URI("http://localhost:" + port)); + rest.getRestTemplate() + .setRequestFactory(new GetWithBodyRequestClientHttpRequestFactory()); + } + + @Test + public void get() { + assertThat(rest.getForObject("/proxy/0", Foo.class).getName()).isEqualTo("bye"); + } + + @Test + public void getWithBodyRequest() { + final HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_JSON); + headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); + + final Foo bodyRequest = new Foo("hello"); + final HttpEntity entity = new HttpEntity<>(bodyRequest, headers); + + final ResponseEntity response = rest.exchange("/proxy/get-with-body-request", + HttpMethod.GET, entity, Foo.class); + + assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); + assertThat(response.getBody()).isInstanceOfSatisfying(Foo.class, + foo -> assertThat(foo.getName()).isEqualTo("hello world")); + } + + @SpringBootApplication + static class TestApplication { + + @Autowired + private ProxyController proxyController; + + public void setHome(URI home) { + proxyController.setHome(home); + } + + @Bean + public ProxyExchangeArgumentResolver proxyExchangeArgumentResolver( + final ProxyProperties proxy) { + ProxyExchangeArgumentResolver resolver = new ProxyExchangeArgumentResolver( + generateConfiguredRestTemplate()); + resolver.setHeaders(proxy.convertHeaders()); + resolver.setAutoForwardedHeaders(proxy.getAutoForward()); + resolver.setSensitive(proxy.getSensitive()); + return resolver; + } + + private RestTemplate generateConfiguredRestTemplate() { + final RestTemplateBuilder builder = new RestTemplateBuilder(); + final RestTemplate template = builder.build(); + + template.setRequestFactory(new GetWithBodyRequestClientHttpRequestFactory()); + template.setErrorHandler(new NoOpResponseErrorHandler()); + template.getMessageConverters().add(new ByteArrayHttpMessageConverter() { + @Override + public boolean supports(Class clazz) { + return true; + } + }); + + return template; + } + + @RestController + static class ProxyController { + + private URI home; + + public void setHome(URI home) { + this.home = home; + } + + @GetMapping("/proxy/{id}") + public ResponseEntity proxyFoos(@PathVariable Integer id, + ProxyExchange proxy) throws Exception { + return proxy.uri(home.toString() + "/foos/" + id).get(); + } + + @GetMapping("/proxy/get-with-body-request") + public ResponseEntity proxyFooWithBody(@RequestBody Foo foo, + ProxyExchange proxy) throws Exception { + return proxy.uri(home.toString() + "/foo/get-with-body-request").get(); + } + } + + @RestController + static class TestController { + + @GetMapping("/foos/{id}") + public Foo foo(@PathVariable Integer id, @RequestHeader HttpHeaders headers) { + String custom = headers.getFirst("X-Custom"); + return new Foo(id == 1 ? "foo" : custom != null ? custom : "bye"); + } + + @GetMapping("/foo/get-with-body-request") + public Foo getWithBody(@RequestBody Foo foo) { + return new Foo(foo.getName() + " world"); + } + } + + @JsonIgnoreProperties(ignoreUnknown = true) + static class Foo { + private String name; + + Foo() { + } + + Foo(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setName(final String name) { + this.name = name; + } + } + + private static class NoOpResponseErrorHandler + extends DefaultResponseErrorHandler { + @Override + public void handleError(ClientHttpResponse response) throws IOException { + } + } + } +} diff --git a/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/ProductionConfigurationTests.java b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/ProductionConfigurationTests.java index c2430e9c..c62dc000 100644 --- a/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/ProductionConfigurationTests.java +++ b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/ProductionConfigurationTests.java @@ -16,17 +16,17 @@ package org.springframework.cloud.gateway.mvc; +import static org.assertj.core.api.Assertions.assertThat; + import java.net.URI; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.context.SpringBootTest; @@ -43,6 +43,7 @@ import org.springframework.http.HttpMethod; import org.springframework.http.HttpStatus; import org.springframework.http.RequestEntity; import org.springframework.http.ResponseEntity; +import org.springframework.http.client.SimpleClientHttpRequestFactory; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; import org.springframework.util.LinkedMultiValueMap; @@ -55,7 +56,7 @@ import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.util.UriComponentsBuilder; -import static org.assertj.core.api.Assertions.assertThat; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; @RunWith(SpringRunner.class) @SpringBootTest(properties = { "spring.cloud.gateway.proxy.auto-forward=Baz" }, @@ -75,6 +76,7 @@ public class ProductionConfigurationTests { @Before public void init() throws Exception { application.setHome(new URI("http://localhost:" + port)); + rest.getRestTemplate().setRequestFactory(new SimpleClientHttpRequestFactory()); } @Test @@ -536,9 +538,6 @@ public class ProductionConfigurationTests { public void setName(String name) { this.name = name; } - } - } - } diff --git a/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/config/ProxyExchangeArgumentResolverTest.java b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/config/ProxyExchangeArgumentResolverTest.java index 9cf70aab..3e874751 100644 --- a/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/config/ProxyExchangeArgumentResolverTest.java +++ b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/config/ProxyExchangeArgumentResolverTest.java @@ -16,6 +16,8 @@ package org.springframework.cloud.gateway.mvc.config; +import static org.assertj.core.api.Assertions.assertThat; + import java.net.URI; import java.util.Collections; import java.util.List; @@ -23,7 +25,6 @@ import java.util.List; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; - import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.context.SpringBootTest; @@ -35,6 +36,7 @@ import org.springframework.cloud.gateway.mvc.ProxyExchange; import org.springframework.context.annotation.Bean; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.http.client.SimpleClientHttpRequestFactory; import org.springframework.http.converter.ByteArrayHttpMessageConverter; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringRunner; @@ -42,8 +44,6 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.DefaultResponseErrorHandler; -import static org.assertj.core.api.Assertions.assertThat; - @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @ContextConfiguration(classes = ProxyExchangeArgumentResolverTest.ProxyExchangeArgumentResolverTestApplication.class) @@ -61,6 +61,7 @@ public class ProxyExchangeArgumentResolverTest { @Before public void setUp() throws Exception { application.setHome(new URI("http://localhost:" + port)); + rest.getRestTemplate().setRequestFactory(new SimpleClientHttpRequestFactory()); } @Test diff --git a/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/http/AbstractBufferingClientHttpRequest.java b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/http/AbstractBufferingClientHttpRequest.java new file mode 100644 index 00000000..2cbe44a4 --- /dev/null +++ b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/http/AbstractBufferingClientHttpRequest.java @@ -0,0 +1,48 @@ +/* + * Copyright 2016-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.gateway.mvc.http; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +import org.springframework.http.HttpHeaders; +import org.springframework.http.client.AbstractClientHttpRequest; +import org.springframework.http.client.ClientHttpResponse; + +abstract class AbstractBufferingClientHttpRequest extends AbstractClientHttpRequest { + private ByteArrayOutputStream bufferedOutput = new ByteArrayOutputStream(1024); + + protected OutputStream getBodyInternal(final HttpHeaders headers) { + return bufferedOutput; + } + + protected abstract ClientHttpResponse executeInternal(final HttpHeaders headers, + final byte[] body) throws IOException; + + protected ClientHttpResponse executeInternal(final HttpHeaders headers) + throws IOException { + final byte[] bytes = bufferedOutput.toByteArray(); + if (headers.getContentLength() < 0L) { + headers.setContentLength(bytes.length); + } + + final ClientHttpResponse response = executeInternal(headers, bytes); + bufferedOutput = new ByteArrayOutputStream(0); + return response; + } +} diff --git a/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/http/GetWithBodyRequestClientHttpRequestFactory.java b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/http/GetWithBodyRequestClientHttpRequestFactory.java new file mode 100644 index 00000000..2aaed08b --- /dev/null +++ b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/http/GetWithBodyRequestClientHttpRequestFactory.java @@ -0,0 +1,123 @@ +/* + * Copyright 2016-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.gateway.mvc.http; + +import java.io.Closeable; +import java.io.IOException; +import java.net.URI; + +import org.apache.http.client.HttpClient; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.client.methods.Configurable; +import org.apache.http.client.methods.HttpDelete; +import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; +import org.apache.http.client.methods.HttpHead; +import org.apache.http.client.methods.HttpOptions; +import org.apache.http.client.methods.HttpPatch; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpPut; +import org.apache.http.client.methods.HttpTrace; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.client.protocol.HttpClientContext; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.protocol.HttpContext; +import org.springframework.beans.factory.DisposableBean; +import org.springframework.http.HttpMethod; +import org.springframework.http.client.ClientHttpRequest; +import org.springframework.http.client.ClientHttpRequestFactory; + +public class GetWithBodyRequestClientHttpRequestFactory + implements ClientHttpRequestFactory, DisposableBean { + private final HttpClient httpClient; + + public GetWithBodyRequestClientHttpRequestFactory() { + this.httpClient = HttpClients.createSystem(); + } + + @Override + public ClientHttpRequest createRequest(final URI uri, final HttpMethod httpMethod) + throws IOException { + final HttpUriRequest httpRequest = createHttpUriRequest(httpMethod, uri); + final HttpContext context = HttpClientContext.create(); + + if (context.getAttribute("http.request-config") == null) { + RequestConfig config = null; + if (httpRequest instanceof Configurable) { + config = ((Configurable) httpRequest).getConfig(); + } + if (config == null) { + config = createRequestConfig(httpClient); + } + if (config != null) { + context.setAttribute("http.request-config", config); + } + } + + return new HttpComponentsClientHttpRequest(httpClient, httpRequest, context); + } + + private HttpUriRequest createHttpUriRequest(final HttpMethod httpMethod, + final URI uri) { + switch (httpMethod) { + case GET: + return new GetWithEntity(uri); + case HEAD: + return new HttpHead(uri); + case POST: + return new HttpPost(uri); + case PUT: + return new HttpPut(uri); + case PATCH: + return new HttpPatch(uri); + case DELETE: + return new HttpDelete(uri); + case OPTIONS: + return new HttpOptions(uri); + case TRACE: + return new HttpTrace(uri); + default: + throw new IllegalArgumentException("Invalid HTTP method: " + httpMethod); + } + } + + private RequestConfig createRequestConfig(final HttpClient client) { + if (client instanceof Configurable) { + return ((Configurable) client).getConfig(); + } + return null; + } + + @Override + public void destroy() throws Exception { + if (httpClient instanceof Closeable) { + ((Closeable) httpClient).close(); + } + } + + public static class GetWithEntity extends HttpEntityEnclosingRequestBase { + public static final String METHOD_NAME = "GET"; + + public GetWithEntity(final URI uri) { + setURI(uri); + } + + @Override + public String getMethod() { + return METHOD_NAME; + } + } +} diff --git a/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/http/HttpComponentsClientHttpRequest.java b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/http/HttpComponentsClientHttpRequest.java new file mode 100644 index 00000000..231796e1 --- /dev/null +++ b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/http/HttpComponentsClientHttpRequest.java @@ -0,0 +1,93 @@ +/* + * Copyright 2016-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.gateway.mvc.http; + +import java.io.IOException; +import java.net.URI; +import java.util.Iterator; + +import org.apache.http.HttpEntityEnclosingRequest; +import org.apache.http.HttpResponse; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpUriRequest; +import org.apache.http.entity.ByteArrayEntity; +import org.apache.http.protocol.HttpContext; +import org.springframework.http.HttpHeaders; +import org.springframework.http.client.ClientHttpResponse; +import org.springframework.util.StringUtils; + +final class HttpComponentsClientHttpRequest extends AbstractBufferingClientHttpRequest { + private static final String COOKIE_HEADER_NAME = "Cookie"; + private static final String CONTENT_LENGTH_HEADER_NAME = "Content-Length"; + private static final String TRANSFER_ENCODING_HEADER_NAME = "Transfer-Encoding"; + + private final HttpClient httpClient; + private final HttpUriRequest httpRequest; + private final HttpContext httpContext; + + HttpComponentsClientHttpRequest(final HttpClient httpClient, + final HttpUriRequest httpRequest, final HttpContext httpContext) { + this.httpClient = httpClient; + this.httpRequest = httpRequest; + this.httpContext = httpContext; + } + + @Override + public String getMethodValue() { + return httpRequest.getMethod(); + } + + @Override + public URI getURI() { + return httpRequest.getURI(); + } + + @Override + protected ClientHttpResponse executeInternal(final HttpHeaders headers, + final byte[] bufferedOutput) throws IOException { + addHeaders(headers); + attachBodyRequest(bufferedOutput); + + final HttpResponse response = httpClient.execute(httpRequest, httpContext); + return new HttpComponentsClientHttpResponse(response); + } + + private void addHeaders(final HttpHeaders headers) { + headers.forEach((headerName, headerValues) -> { + if (COOKIE_HEADER_NAME.equalsIgnoreCase(headerName)) { + String headerValue = StringUtils.collectionToDelimitedString(headerValues, + ": "); + httpRequest.addHeader(headerName, headerValue); + } + else if (!CONTENT_LENGTH_HEADER_NAME.equalsIgnoreCase(headerName) + && !TRANSFER_ENCODING_HEADER_NAME.equalsIgnoreCase(headerName)) { + final Iterator it = headerValues.iterator(); + while (it.hasNext()) { + String value = it.next(); + httpRequest.addHeader(headerName, value); + } + } + }); + } + + private void attachBodyRequest(final byte[] bufferedOutput) { + if (httpRequest instanceof HttpEntityEnclosingRequest) { + ((HttpEntityEnclosingRequest) httpRequest) + .setEntity(new ByteArrayEntity(bufferedOutput)); + } + } +} diff --git a/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/http/HttpComponentsClientHttpResponse.java b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/http/HttpComponentsClientHttpResponse.java new file mode 100644 index 00000000..40323ae8 --- /dev/null +++ b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/http/HttpComponentsClientHttpResponse.java @@ -0,0 +1,84 @@ +/* + * Copyright 2016-2019 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.cloud.gateway.mvc.http; + +import java.io.Closeable; +import java.io.IOException; +import java.io.InputStream; + +import org.apache.http.Header; +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.util.EntityUtils; +import org.springframework.http.HttpHeaders; +import org.springframework.http.client.AbstractClientHttpResponse; +import org.springframework.lang.Nullable; +import org.springframework.util.StreamUtils; + +final class HttpComponentsClientHttpResponse extends AbstractClientHttpResponse { + private final HttpResponse response; + @Nullable + private HttpHeaders headers; + + HttpComponentsClientHttpResponse(final HttpResponse response) { + this.response = response; + } + + @Override + public int getRawStatusCode() throws IOException { + return response.getStatusLine().getStatusCode(); + } + + @Override + public String getStatusText() throws IOException { + return response.getStatusLine().getReasonPhrase(); + } + + @Override + public HttpHeaders getHeaders() { + if (headers == null) { + headers = new HttpHeaders(); + final Header[] responseHeaders = response.getAllHeaders(); + for (Header header : responseHeaders) { + headers.add(header.getName(), header.getValue()); + } + } + return headers; + } + + @Override + public InputStream getBody() throws IOException { + final HttpEntity entity = response.getEntity(); + return entity != null ? entity.getContent() : StreamUtils.emptyInput(); + } + + @Override + public void close() { + try { + try { + EntityUtils.consume(response.getEntity()); + } + finally { + if (response instanceof Closeable) { + ((Closeable) response).close(); + } + } + } + catch (IOException ignored) { + } + } +} From fb49b8789d9fbcbe3530743b86c9b110a15fb6ce Mon Sep 17 00:00:00 2001 From: spencergibb Date: Fri, 10 Dec 2021 12:06:28 -0500 Subject: [PATCH 3/4] formatting and checkstyle --- .../cloud/gateway/mvc/ProxyExchange.java | 3 +- .../gateway/mvc/GetWithBodyRequestTest.java | 33 ++++++++++--------- .../mvc/ProductionConfigurationTests.java | 9 +++-- .../ProxyExchangeArgumentResolverTest.java | 5 +-- .../AbstractBufferingClientHttpRequest.java | 10 +++--- ...thBodyRequestClientHttpRequestFactory.java | 14 ++++---- .../http/HttpComponentsClientHttpRequest.java | 21 +++++++----- .../HttpComponentsClientHttpResponse.java | 4 +++ 8 files changed, 58 insertions(+), 41 deletions(-) diff --git a/spring-cloud-gateway-mvc/src/main/java/org/springframework/cloud/gateway/mvc/ProxyExchange.java b/spring-cloud-gateway-mvc/src/main/java/org/springframework/cloud/gateway/mvc/ProxyExchange.java index 31828ffe..81206e5a 100644 --- a/spring-cloud-gateway-mvc/src/main/java/org/springframework/cloud/gateway/mvc/ProxyExchange.java +++ b/spring-cloud-gateway-mvc/src/main/java/org/springframework/cloud/gateway/mvc/ProxyExchange.java @@ -277,8 +277,7 @@ public class ProxyExchange { } public ResponseEntity get() { - RequestEntity requestEntity = headers((BodyBuilder) RequestEntity.get(uri)) - .body(body()); + RequestEntity requestEntity = headers((BodyBuilder) RequestEntity.get(uri)).body(body()); return exchange(requestEntity); } diff --git a/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/GetWithBodyRequestTest.java b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/GetWithBodyRequestTest.java index 41d951e7..9836dae9 100644 --- a/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/GetWithBodyRequestTest.java +++ b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/GetWithBodyRequestTest.java @@ -16,15 +16,15 @@ package org.springframework.cloud.gateway.mvc; -import static org.assertj.core.api.Assertions.assertThat; - import java.io.IOException; import java.net.URI; import java.util.Collections; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.context.SpringBootTest; @@ -54,7 +54,7 @@ import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.DefaultResponseErrorHandler; import org.springframework.web.client.RestTemplate; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import static org.assertj.core.api.Assertions.assertThat; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) @@ -73,8 +73,7 @@ public class GetWithBodyRequestTest { @Before public void init() throws Exception { testApplication.setHome(new URI("http://localhost:" + port)); - rest.getRestTemplate() - .setRequestFactory(new GetWithBodyRequestClientHttpRequestFactory()); + rest.getRestTemplate().setRequestFactory(new GetWithBodyRequestClientHttpRequestFactory()); } @Test @@ -91,8 +90,8 @@ public class GetWithBodyRequestTest { final Foo bodyRequest = new Foo("hello"); final HttpEntity entity = new HttpEntity<>(bodyRequest, headers); - final ResponseEntity response = rest.exchange("/proxy/get-with-body-request", - HttpMethod.GET, entity, Foo.class); + final ResponseEntity response = rest.exchange("/proxy/get-with-body-request", HttpMethod.GET, entity, + Foo.class); assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK); assertThat(response.getBody()).isInstanceOfSatisfying(Foo.class, @@ -110,8 +109,7 @@ public class GetWithBodyRequestTest { } @Bean - public ProxyExchangeArgumentResolver proxyExchangeArgumentResolver( - final ProxyProperties proxy) { + public ProxyExchangeArgumentResolver proxyExchangeArgumentResolver(final ProxyProperties proxy) { ProxyExchangeArgumentResolver resolver = new ProxyExchangeArgumentResolver( generateConfiguredRestTemplate()); resolver.setHeaders(proxy.convertHeaders()); @@ -146,16 +144,15 @@ public class GetWithBodyRequestTest { } @GetMapping("/proxy/{id}") - public ResponseEntity proxyFoos(@PathVariable Integer id, - ProxyExchange proxy) throws Exception { + public ResponseEntity proxyFoos(@PathVariable Integer id, ProxyExchange proxy) throws Exception { return proxy.uri(home.toString() + "/foos/" + id).get(); } @GetMapping("/proxy/get-with-body-request") - public ResponseEntity proxyFooWithBody(@RequestBody Foo foo, - ProxyExchange proxy) throws Exception { + public ResponseEntity proxyFooWithBody(@RequestBody Foo foo, ProxyExchange proxy) throws Exception { return proxy.uri(home.toString() + "/foo/get-with-body-request").get(); } + } @RestController @@ -171,10 +168,12 @@ public class GetWithBodyRequestTest { public Foo getWithBody(@RequestBody Foo foo) { return new Foo(foo.getName() + " world"); } + } @JsonIgnoreProperties(ignoreUnknown = true) static class Foo { + private String name; Foo() { @@ -191,13 +190,17 @@ public class GetWithBodyRequestTest { public void setName(final String name) { this.name = name; } + } - private static class NoOpResponseErrorHandler - extends DefaultResponseErrorHandler { + private static class NoOpResponseErrorHandler extends DefaultResponseErrorHandler { + @Override public void handleError(ClientHttpResponse response) throws IOException { } + } + } + } diff --git a/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/ProductionConfigurationTests.java b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/ProductionConfigurationTests.java index c62dc000..74eb4c6e 100644 --- a/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/ProductionConfigurationTests.java +++ b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/ProductionConfigurationTests.java @@ -16,17 +16,17 @@ package org.springframework.cloud.gateway.mvc; -import static org.assertj.core.api.Assertions.assertThat; - import java.net.URI; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.context.SpringBootTest; @@ -56,7 +56,7 @@ import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.util.UriComponentsBuilder; -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import static org.assertj.core.api.Assertions.assertThat; @RunWith(SpringRunner.class) @SpringBootTest(properties = { "spring.cloud.gateway.proxy.auto-forward=Baz" }, @@ -538,6 +538,9 @@ public class ProductionConfigurationTests { public void setName(String name) { this.name = name; } + } + } + } diff --git a/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/config/ProxyExchangeArgumentResolverTest.java b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/config/ProxyExchangeArgumentResolverTest.java index 3e874751..97a859c8 100644 --- a/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/config/ProxyExchangeArgumentResolverTest.java +++ b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/config/ProxyExchangeArgumentResolverTest.java @@ -16,8 +16,6 @@ package org.springframework.cloud.gateway.mvc.config; -import static org.assertj.core.api.Assertions.assertThat; - import java.net.URI; import java.util.Collections; import java.util.List; @@ -25,6 +23,7 @@ import java.util.List; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; + import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.test.context.SpringBootTest; @@ -44,6 +43,8 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.DefaultResponseErrorHandler; +import static org.assertj.core.api.Assertions.assertThat; + @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT) @ContextConfiguration(classes = ProxyExchangeArgumentResolverTest.ProxyExchangeArgumentResolverTestApplication.class) diff --git a/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/http/AbstractBufferingClientHttpRequest.java b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/http/AbstractBufferingClientHttpRequest.java index 2cbe44a4..64dfa458 100644 --- a/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/http/AbstractBufferingClientHttpRequest.java +++ b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/http/AbstractBufferingClientHttpRequest.java @@ -25,17 +25,16 @@ import org.springframework.http.client.AbstractClientHttpRequest; import org.springframework.http.client.ClientHttpResponse; abstract class AbstractBufferingClientHttpRequest extends AbstractClientHttpRequest { + private ByteArrayOutputStream bufferedOutput = new ByteArrayOutputStream(1024); - protected OutputStream getBodyInternal(final HttpHeaders headers) { + protected OutputStream getBodyInternal(HttpHeaders headers) { return bufferedOutput; } - protected abstract ClientHttpResponse executeInternal(final HttpHeaders headers, - final byte[] body) throws IOException; + protected abstract ClientHttpResponse executeInternal(HttpHeaders headers, byte[] body) throws IOException; - protected ClientHttpResponse executeInternal(final HttpHeaders headers) - throws IOException { + protected ClientHttpResponse executeInternal(HttpHeaders headers) throws IOException { final byte[] bytes = bufferedOutput.toByteArray(); if (headers.getContentLength() < 0L) { headers.setContentLength(bytes.length); @@ -45,4 +44,5 @@ abstract class AbstractBufferingClientHttpRequest extends AbstractClientHttpRequ bufferedOutput = new ByteArrayOutputStream(0); return response; } + } diff --git a/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/http/GetWithBodyRequestClientHttpRequestFactory.java b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/http/GetWithBodyRequestClientHttpRequestFactory.java index 2aaed08b..8dcee63b 100644 --- a/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/http/GetWithBodyRequestClientHttpRequestFactory.java +++ b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/http/GetWithBodyRequestClientHttpRequestFactory.java @@ -35,13 +35,14 @@ import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.client.protocol.HttpClientContext; import org.apache.http.impl.client.HttpClients; import org.apache.http.protocol.HttpContext; + import org.springframework.beans.factory.DisposableBean; import org.springframework.http.HttpMethod; import org.springframework.http.client.ClientHttpRequest; import org.springframework.http.client.ClientHttpRequestFactory; -public class GetWithBodyRequestClientHttpRequestFactory - implements ClientHttpRequestFactory, DisposableBean { +public class GetWithBodyRequestClientHttpRequestFactory implements ClientHttpRequestFactory, DisposableBean { + private final HttpClient httpClient; public GetWithBodyRequestClientHttpRequestFactory() { @@ -49,8 +50,7 @@ public class GetWithBodyRequestClientHttpRequestFactory } @Override - public ClientHttpRequest createRequest(final URI uri, final HttpMethod httpMethod) - throws IOException { + public ClientHttpRequest createRequest(final URI uri, final HttpMethod httpMethod) throws IOException { final HttpUriRequest httpRequest = createHttpUriRequest(httpMethod, uri); final HttpContext context = HttpClientContext.create(); @@ -70,8 +70,7 @@ public class GetWithBodyRequestClientHttpRequestFactory return new HttpComponentsClientHttpRequest(httpClient, httpRequest, context); } - private HttpUriRequest createHttpUriRequest(final HttpMethod httpMethod, - final URI uri) { + private HttpUriRequest createHttpUriRequest(final HttpMethod httpMethod, final URI uri) { switch (httpMethod) { case GET: return new GetWithEntity(uri); @@ -109,6 +108,7 @@ public class GetWithBodyRequestClientHttpRequestFactory } public static class GetWithEntity extends HttpEntityEnclosingRequestBase { + public static final String METHOD_NAME = "GET"; public GetWithEntity(final URI uri) { @@ -119,5 +119,7 @@ public class GetWithBodyRequestClientHttpRequestFactory public String getMethod() { return METHOD_NAME; } + } + } diff --git a/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/http/HttpComponentsClientHttpRequest.java b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/http/HttpComponentsClientHttpRequest.java index 231796e1..d499d6f8 100644 --- a/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/http/HttpComponentsClientHttpRequest.java +++ b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/http/HttpComponentsClientHttpRequest.java @@ -26,21 +26,27 @@ import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpUriRequest; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.protocol.HttpContext; + import org.springframework.http.HttpHeaders; import org.springframework.http.client.ClientHttpResponse; import org.springframework.util.StringUtils; final class HttpComponentsClientHttpRequest extends AbstractBufferingClientHttpRequest { + private static final String COOKIE_HEADER_NAME = "Cookie"; + private static final String CONTENT_LENGTH_HEADER_NAME = "Content-Length"; + private static final String TRANSFER_ENCODING_HEADER_NAME = "Transfer-Encoding"; private final HttpClient httpClient; + private final HttpUriRequest httpRequest; + private final HttpContext httpContext; - HttpComponentsClientHttpRequest(final HttpClient httpClient, - final HttpUriRequest httpRequest, final HttpContext httpContext) { + HttpComponentsClientHttpRequest(final HttpClient httpClient, final HttpUriRequest httpRequest, + final HttpContext httpContext) { this.httpClient = httpClient; this.httpRequest = httpRequest; this.httpContext = httpContext; @@ -57,8 +63,8 @@ final class HttpComponentsClientHttpRequest extends AbstractBufferingClientHttpR } @Override - protected ClientHttpResponse executeInternal(final HttpHeaders headers, - final byte[] bufferedOutput) throws IOException { + protected ClientHttpResponse executeInternal(final HttpHeaders headers, final byte[] bufferedOutput) + throws IOException { addHeaders(headers); attachBodyRequest(bufferedOutput); @@ -69,8 +75,7 @@ final class HttpComponentsClientHttpRequest extends AbstractBufferingClientHttpR private void addHeaders(final HttpHeaders headers) { headers.forEach((headerName, headerValues) -> { if (COOKIE_HEADER_NAME.equalsIgnoreCase(headerName)) { - String headerValue = StringUtils.collectionToDelimitedString(headerValues, - ": "); + String headerValue = StringUtils.collectionToDelimitedString(headerValues, ": "); httpRequest.addHeader(headerName, headerValue); } else if (!CONTENT_LENGTH_HEADER_NAME.equalsIgnoreCase(headerName) @@ -86,8 +91,8 @@ final class HttpComponentsClientHttpRequest extends AbstractBufferingClientHttpR private void attachBodyRequest(final byte[] bufferedOutput) { if (httpRequest instanceof HttpEntityEnclosingRequest) { - ((HttpEntityEnclosingRequest) httpRequest) - .setEntity(new ByteArrayEntity(bufferedOutput)); + ((HttpEntityEnclosingRequest) httpRequest).setEntity(new ByteArrayEntity(bufferedOutput)); } } + } diff --git a/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/http/HttpComponentsClientHttpResponse.java b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/http/HttpComponentsClientHttpResponse.java index 40323ae8..39f0e4b3 100644 --- a/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/http/HttpComponentsClientHttpResponse.java +++ b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/http/HttpComponentsClientHttpResponse.java @@ -24,13 +24,16 @@ import org.apache.http.Header; import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.util.EntityUtils; + import org.springframework.http.HttpHeaders; import org.springframework.http.client.AbstractClientHttpResponse; import org.springframework.lang.Nullable; import org.springframework.util.StreamUtils; final class HttpComponentsClientHttpResponse extends AbstractClientHttpResponse { + private final HttpResponse response; + @Nullable private HttpHeaders headers; @@ -81,4 +84,5 @@ final class HttpComponentsClientHttpResponse extends AbstractClientHttpResponse catch (IOException ignored) { } } + } From b65fb26fa4fb66f83e4a39ec406cc97a64f6db79 Mon Sep 17 00:00:00 2001 From: spencergibb Date: Fri, 10 Dec 2021 12:07:31 -0500 Subject: [PATCH 4/4] renamed GetWithBodyRequestTests --- ...ithBodyRequestTest.java => GetWithBodyRequestTests.java} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/{GetWithBodyRequestTest.java => GetWithBodyRequestTests.java} (97%) diff --git a/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/GetWithBodyRequestTest.java b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/GetWithBodyRequestTests.java similarity index 97% rename from spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/GetWithBodyRequestTest.java rename to spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/GetWithBodyRequestTests.java index 9836dae9..59c770c3 100644 --- a/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/GetWithBodyRequestTest.java +++ b/spring-cloud-gateway-mvc/src/test/java/org/springframework/cloud/gateway/mvc/GetWithBodyRequestTests.java @@ -31,7 +31,7 @@ import org.springframework.boot.test.context.SpringBootTest; import org.springframework.boot.test.web.client.TestRestTemplate; import org.springframework.boot.web.client.RestTemplateBuilder; import org.springframework.boot.web.server.LocalServerPort; -import org.springframework.cloud.gateway.mvc.GetWithBodyRequestTest.TestApplication.Foo; +import org.springframework.cloud.gateway.mvc.GetWithBodyRequestTests.TestApplication.Foo; import org.springframework.cloud.gateway.mvc.config.ProxyExchangeArgumentResolver; import org.springframework.cloud.gateway.mvc.config.ProxyProperties; import org.springframework.cloud.gateway.mvc.http.GetWithBodyRequestClientHttpRequestFactory; @@ -58,8 +58,8 @@ import static org.assertj.core.api.Assertions.assertThat; @RunWith(SpringRunner.class) @SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) -@ContextConfiguration(classes = GetWithBodyRequestTest.TestApplication.class) -public class GetWithBodyRequestTest { +@ContextConfiguration(classes = GetWithBodyRequestTests.TestApplication.class) +public class GetWithBodyRequestTests { @Autowired private TestRestTemplate rest;