From f5d689e764b9feebe4595a6f7832238be6cfb68c Mon Sep 17 00:00:00 2001 From: Brian Bohl Date: Wed, 23 Aug 2017 15:16:47 -0500 Subject: [PATCH] Fix StringIndexOutOfBoundsException in RestTemplate Backport for commits #81dfad and #3d61f7 Issue: SPR-15900 --- .../web/client/RestTemplate.java | 2 +- .../web/client/RestTemplateTests.java | 41 ++++++++++++++++--- 2 files changed, 37 insertions(+), 6 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/client/RestTemplate.java b/spring-web/src/main/java/org/springframework/web/client/RestTemplate.java index 0b8734443e..333ab0c23c 100644 --- a/spring-web/src/main/java/org/springframework/web/client/RestTemplate.java +++ b/spring-web/src/main/java/org/springframework/web/client/RestTemplate.java @@ -661,7 +661,7 @@ public class RestTemplate extends InterceptingHttpAccessor implements RestOperat catch (IOException ex) { String resource = url.toString(); String query = url.getRawQuery(); - resource = (query != null ? resource.substring(0, resource.indexOf(query) - 1) : resource); + resource = (query != null ? resource.substring(0, resource.indexOf('?')) : resource); throw new ResourceAccessException("I/O error on " + method.name() + " request for \"" + resource + "\": " + ex.getMessage(), ex); } diff --git a/spring-web/src/test/java/org/springframework/web/client/RestTemplateTests.java b/spring-web/src/test/java/org/springframework/web/client/RestTemplateTests.java index f70833589d..6e3236d358 100644 --- a/spring-web/src/test/java/org/springframework/web/client/RestTemplateTests.java +++ b/spring-web/src/test/java/org/springframework/web/client/RestTemplateTests.java @@ -44,8 +44,18 @@ import org.springframework.http.converter.GenericHttpMessageConverter; import org.springframework.http.converter.HttpMessageConverter; import org.springframework.web.util.DefaultUriTemplateHandler; -import static org.junit.Assert.*; -import static org.mockito.BDDMockito.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertSame; +import static org.junit.Assert.fail; +import static org.mockito.BDDMockito.any; +import static org.mockito.BDDMockito.eq; +import static org.mockito.BDDMockito.given; +import static org.mockito.BDDMockito.mock; +import static org.mockito.BDDMockito.verify; +import static org.mockito.BDDMockito.willThrow; +import static org.springframework.http.MediaType.parseMediaType; /** * @author Arjen Poutsma @@ -701,9 +711,7 @@ public class RestTemplateTests { verify(response).close(); } - // Issue: SPR-9325, SPR-13860 - - @Test + @Test // Issue: SPR-9325, SPR-13860 public void ioException() throws Exception { String url = "http://example.com/resource?access_token=123"; @@ -725,6 +733,29 @@ public class RestTemplateTests { } } + @Test // SPR-15900 + public void ioExceptionWithEmptyQueryString() throws Exception { + + // http://example.com/resource? + URI uri = new URI("http", "example.com", "/resource", "", null); + + given(converter.canRead(String.class, null)).willReturn(true); + given(converter.getSupportedMediaTypes()).willReturn(Collections.singletonList(parseMediaType("foo/bar"))); + given(requestFactory.createRequest(uri, HttpMethod.GET)).willReturn(request); + given(request.getHeaders()).willReturn(new HttpHeaders()); + given(request.execute()).willThrow(new IOException("Socket failure")); + + try { + template.getForObject(uri, String.class); + fail("RestClientException expected"); + } + catch (ResourceAccessException ex) { + assertEquals("I/O error on GET request for \"http://example.com/resource\": " + + "Socket failure; nested exception is java.io.IOException: Socket failure", + ex.getMessage()); + } + } + @Test public void exchange() throws Exception { given(converter.canRead(Integer.class, null)).willReturn(true);