Merge branch '3.0.x'
This commit is contained in:
@@ -40,6 +40,11 @@
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.httpcomponents</groupId>
|
||||
<artifactId>httpclient</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
|
||||
@@ -277,7 +277,7 @@ public class ProxyExchange<T> {
|
||||
}
|
||||
|
||||
public ResponseEntity<T> get() {
|
||||
RequestEntity<?> requestEntity = headers((BodyBuilder) RequestEntity.get(uri)).build();
|
||||
RequestEntity<?> requestEntity = headers((BodyBuilder) RequestEntity.get(uri)).body(body());
|
||||
return exchange(requestEntity);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* 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 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;
|
||||
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.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;
|
||||
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 static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
@RunWith(SpringRunner.class)
|
||||
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
|
||||
@ContextConfiguration(classes = GetWithBodyRequestTests.TestApplication.class)
|
||||
public class GetWithBodyRequestTests {
|
||||
|
||||
@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<Foo> entity = new HttpEntity<>(bodyRequest, headers);
|
||||
|
||||
final ResponseEntity<Foo> 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 {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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
|
||||
|
||||
@@ -35,6 +35,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;
|
||||
@@ -61,6 +62,7 @@ public class ProxyExchangeArgumentResolverTest {
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
application.setHome(new URI("http://localhost:" + port));
|
||||
rest.getRestTemplate().setRequestFactory(new SimpleClientHttpRequestFactory());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -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(HttpHeaders headers) {
|
||||
return bufferedOutput;
|
||||
}
|
||||
|
||||
protected abstract ClientHttpResponse executeInternal(HttpHeaders headers, byte[] body) throws IOException;
|
||||
|
||||
protected ClientHttpResponse executeInternal(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;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* 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<String> 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));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* 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) {
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user