Skip to content

Commit f5d689e

Browse files
Brian Bohlrstoyanchev
Brian Bohl
authored andcommitted
Fix StringIndexOutOfBoundsException in RestTemplate
Backport for commits #81dfad and #3d61f7 Issue: SPR-15900
1 parent 681ced8 commit f5d689e

File tree

2 files changed

+37
-6
lines changed

2 files changed

+37
-6
lines changed

spring-web/src/main/java/org/springframework/web/client/RestTemplate.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -661,7 +661,7 @@ protected <T> T doExecute(URI url, HttpMethod method, RequestCallback requestCal
661661
catch (IOException ex) {
662662
String resource = url.toString();
663663
String query = url.getRawQuery();
664-
resource = (query != null ? resource.substring(0, resource.indexOf(query) - 1) : resource);
664+
resource = (query != null ? resource.substring(0, resource.indexOf('?')) : resource);
665665
throw new ResourceAccessException("I/O error on " + method.name() +
666666
" request for \"" + resource + "\": " + ex.getMessage(), ex);
667667
}

spring-web/src/test/java/org/springframework/web/client/RestTemplateTests.java

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,18 @@
4444
import org.springframework.http.converter.HttpMessageConverter;
4545
import org.springframework.web.util.DefaultUriTemplateHandler;
4646

47-
import static org.junit.Assert.*;
48-
import static org.mockito.BDDMockito.*;
47+
import static org.junit.Assert.assertEquals;
48+
import static org.junit.Assert.assertFalse;
49+
import static org.junit.Assert.assertNull;
50+
import static org.junit.Assert.assertSame;
51+
import static org.junit.Assert.fail;
52+
import static org.mockito.BDDMockito.any;
53+
import static org.mockito.BDDMockito.eq;
54+
import static org.mockito.BDDMockito.given;
55+
import static org.mockito.BDDMockito.mock;
56+
import static org.mockito.BDDMockito.verify;
57+
import static org.mockito.BDDMockito.willThrow;
58+
import static org.springframework.http.MediaType.parseMediaType;
4959

5060
/**
5161
* @author Arjen Poutsma
@@ -701,9 +711,7 @@ public void optionsForAllow() throws Exception {
701711
verify(response).close();
702712
}
703713

704-
// Issue: SPR-9325, SPR-13860
705-
706-
@Test
714+
@Test // Issue: SPR-9325, SPR-13860
707715
public void ioException() throws Exception {
708716
String url = "http://example.com/resource?access_token=123";
709717

@@ -725,6 +733,29 @@ public void ioException() throws Exception {
725733
}
726734
}
727735

736+
@Test // SPR-15900
737+
public void ioExceptionWithEmptyQueryString() throws Exception {
738+
739+
// http://example.com/resource?
740+
URI uri = new URI("http", "example.com", "/resource", "", null);
741+
742+
given(converter.canRead(String.class, null)).willReturn(true);
743+
given(converter.getSupportedMediaTypes()).willReturn(Collections.singletonList(parseMediaType("foo/bar")));
744+
given(requestFactory.createRequest(uri, HttpMethod.GET)).willReturn(request);
745+
given(request.getHeaders()).willReturn(new HttpHeaders());
746+
given(request.execute()).willThrow(new IOException("Socket failure"));
747+
748+
try {
749+
template.getForObject(uri, String.class);
750+
fail("RestClientException expected");
751+
}
752+
catch (ResourceAccessException ex) {
753+
assertEquals("I/O error on GET request for \"http://example.com/resource\": " +
754+
"Socket failure; nested exception is java.io.IOException: Socket failure",
755+
ex.getMessage());
756+
}
757+
}
758+
728759
@Test
729760
public void exchange() throws Exception {
730761
given(converter.canRead(Integer.class, null)).willReturn(true);

0 commit comments

Comments
 (0)