Skip to content

Commit 7b05bf3

Browse files
committed
RestTemplateEurekaHttpClient - Encode special characters; fixes spring-cloudgh-4121
1 parent aa9ba18 commit 7b05bf3

File tree

1 file changed

+39
-26
lines changed

1 file changed

+39
-26
lines changed

spring-cloud-netflix-eureka-client/src/main/java/org/springframework/cloud/netflix/eureka/http/RestTemplateEurekaHttpClient.java

+39-26
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616

1717
package org.springframework.cloud.netflix.eureka.http;
1818

19+
import java.net.URI;
1920
import java.util.Collections;
2021
import java.util.HashMap;
2122
import java.util.List;
@@ -40,6 +41,7 @@
4041
import org.springframework.http.MediaType;
4142
import org.springframework.http.ResponseEntity;
4243
import org.springframework.web.client.RestTemplate;
44+
import org.springframework.web.util.UriComponentsBuilder;
4345

4446
import static com.netflix.discovery.shared.transport.EurekaHttpResponse.anEurekaHttpResponse;
4547

@@ -68,36 +70,43 @@ public String getServiceUrl() {
6870

6971
@Override
7072
public EurekaHttpResponse<Void> register(InstanceInfo info) {
71-
String urlPath = serviceUrl + "apps/" + info.getAppName();
73+
URI uri = UriComponentsBuilder.fromHttpUrl(serviceUrl).path("apps/{appName}").buildAndExpand(info.getAppName())
74+
.toUri();
7275

7376
HttpHeaders headers = new HttpHeaders();
7477
headers.add(HttpHeaders.ACCEPT_ENCODING, "gzip");
7578
headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
7679

77-
ResponseEntity<Void> response = restTemplate.exchange(urlPath, HttpMethod.POST, new HttpEntity<>(info, headers),
80+
ResponseEntity<Void> response = restTemplate.exchange(uri, HttpMethod.POST, new HttpEntity<>(info, headers),
7881
Void.class);
7982

8083
return anEurekaHttpResponse(response.getStatusCodeValue()).headers(headersOf(response)).build();
8184
}
8285

8386
@Override
8487
public EurekaHttpResponse<Void> cancel(String appName, String id) {
85-
String urlPath = serviceUrl + "apps/" + appName + '/' + id;
88+
URI uri = UriComponentsBuilder.fromHttpUrl(serviceUrl).path("apps/{appName}/{id}").buildAndExpand(appName, id)
89+
.toUri();
8690

87-
ResponseEntity<Void> response = restTemplate.exchange(urlPath, HttpMethod.DELETE, null, Void.class);
91+
ResponseEntity<Void> response = restTemplate.exchange(uri, HttpMethod.DELETE, null, Void.class);
8892

8993
return anEurekaHttpResponse(response.getStatusCodeValue()).headers(headersOf(response)).build();
9094
}
9195

9296
@Override
9397
public EurekaHttpResponse<InstanceInfo> sendHeartBeat(String appName, String id, InstanceInfo info,
9498
InstanceStatus overriddenStatus) {
95-
String urlPath = serviceUrl + "apps/" + appName + '/' + id + "?status=" + info.getStatus().toString()
96-
+ "&lastDirtyTimestamp=" + info.getLastDirtyTimestamp().toString()
97-
+ (overriddenStatus != null ? "&overriddenstatus=" + overriddenStatus.name() : "");
99+
UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(serviceUrl).path("apps/{appName}/{id}")
100+
.queryParam("status", info.getStatus().toString())
101+
.queryParam("lastDirtyTimestamp", info.getLastDirtyTimestamp().toString());
98102

99-
ResponseEntity<InstanceInfo> response = restTemplate.exchange(urlPath, HttpMethod.PUT, null,
100-
InstanceInfo.class);
103+
if (overriddenStatus != null) {
104+
uriBuilder = uriBuilder.queryParam("overriddenstatus", overriddenStatus.name());
105+
}
106+
107+
URI uri = uriBuilder.buildAndExpand(appName, id).toUri();
108+
109+
ResponseEntity<InstanceInfo> response = restTemplate.exchange(uri, HttpMethod.PUT, null, InstanceInfo.class);
101110

102111
EurekaHttpResponseBuilder<InstanceInfo> eurekaResponseBuilder = anEurekaHttpResponse(
103112
response.getStatusCodeValue(), InstanceInfo.class).headers(headersOf(response));
@@ -112,20 +121,23 @@ public EurekaHttpResponse<InstanceInfo> sendHeartBeat(String appName, String id,
112121
@Override
113122
public EurekaHttpResponse<Void> statusUpdate(String appName, String id, InstanceStatus newStatus,
114123
InstanceInfo info) {
115-
String urlPath = serviceUrl + "apps/" + appName + '/' + id + "/status?value=" + newStatus.name()
116-
+ "&lastDirtyTimestamp=" + info.getLastDirtyTimestamp().toString();
124+
URI uri = UriComponentsBuilder.fromHttpUrl(serviceUrl).path("apps/{appName}/{id}/status")
125+
.queryParam("value", newStatus.name())
126+
.queryParam("lastDirtyTimestamp", info.getLastDirtyTimestamp().toString()).buildAndExpand(appName, id)
127+
.toUri();
117128

118-
ResponseEntity<Void> response = restTemplate.exchange(urlPath, HttpMethod.PUT, null, Void.class);
129+
ResponseEntity<Void> response = restTemplate.exchange(uri, HttpMethod.PUT, null, Void.class);
119130

120131
return anEurekaHttpResponse(response.getStatusCodeValue()).headers(headersOf(response)).build();
121132
}
122133

123134
@Override
124135
public EurekaHttpResponse<Void> deleteStatusOverride(String appName, String id, InstanceInfo info) {
125-
String urlPath = serviceUrl + "apps/" + appName + '/' + id + "/status?lastDirtyTimestamp="
126-
+ info.getLastDirtyTimestamp().toString();
136+
URI uri = UriComponentsBuilder.fromHttpUrl(serviceUrl).path("apps/{appName}/{id}/status")
137+
.queryParam("lastDirtyTimestamp", info.getLastDirtyTimestamp().toString()).buildAndExpand(appName, id)
138+
.toUri();
127139

128-
ResponseEntity<Void> response = restTemplate.exchange(urlPath, HttpMethod.DELETE, null, Void.class);
140+
ResponseEntity<Void> response = restTemplate.exchange(uri, HttpMethod.DELETE, null, Void.class);
129141

130142
return anEurekaHttpResponse(response.getStatusCodeValue()).headers(headersOf(response)).build();
131143
}
@@ -136,13 +148,15 @@ public EurekaHttpResponse<Applications> getApplications(String... regions) {
136148
}
137149

138150
private EurekaHttpResponse<Applications> getApplicationsInternal(String urlPath, String[] regions) {
139-
String url = serviceUrl + urlPath;
151+
UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(serviceUrl).path(urlPath);
140152

141153
if (regions != null && regions.length > 0) {
142-
url = url + (urlPath.contains("?") ? "&" : "?") + "regions=" + StringUtil.join(regions);
154+
uriBuilder = uriBuilder.queryParam("regions", StringUtil.join(regions));
143155
}
144156

145-
ResponseEntity<EurekaApplications> response = restTemplate.exchange(url, HttpMethod.GET, null,
157+
URI uri = uriBuilder.build().toUri();
158+
159+
ResponseEntity<EurekaApplications> response = restTemplate.exchange(uri, HttpMethod.GET, null,
146160
EurekaApplications.class);
147161

148162
return anEurekaHttpResponse(response.getStatusCodeValue(),
@@ -167,9 +181,9 @@ public EurekaHttpResponse<Applications> getSecureVip(String secureVipAddress, St
167181

168182
@Override
169183
public EurekaHttpResponse<Application> getApplication(String appName) {
170-
String urlPath = serviceUrl + "apps/" + appName;
184+
URI uri = UriComponentsBuilder.fromHttpUrl(serviceUrl).path("apps/{appName}").buildAndExpand(appName).toUri();
171185

172-
ResponseEntity<Application> response = restTemplate.exchange(urlPath, HttpMethod.GET, null, Application.class);
186+
ResponseEntity<Application> response = restTemplate.exchange(uri, HttpMethod.GET, null, Application.class);
173187

174188
Application application = response.getStatusCodeValue() == HttpStatus.OK.value() && response.hasBody()
175189
? response.getBody() : null;
@@ -179,19 +193,18 @@ public EurekaHttpResponse<Application> getApplication(String appName) {
179193

180194
@Override
181195
public EurekaHttpResponse<InstanceInfo> getInstance(String appName, String id) {
182-
return getInstanceInternal("apps/" + appName + '/' + id);
196+
return getInstanceInternal("apps", appName, id);
183197
}
184198

185199
@Override
186200
public EurekaHttpResponse<InstanceInfo> getInstance(String id) {
187-
return getInstanceInternal("instances/" + id);
201+
return getInstanceInternal("instances", id);
188202
}
189203

190-
private EurekaHttpResponse<InstanceInfo> getInstanceInternal(String urlPath) {
191-
urlPath = serviceUrl + urlPath;
204+
private EurekaHttpResponse<InstanceInfo> getInstanceInternal(String... pathSegments) {
205+
URI uri = UriComponentsBuilder.fromHttpUrl(serviceUrl).pathSegment(pathSegments).build().toUri();
192206

193-
ResponseEntity<InstanceInfo> response = restTemplate.exchange(urlPath, HttpMethod.GET, null,
194-
InstanceInfo.class);
207+
ResponseEntity<InstanceInfo> response = restTemplate.exchange(uri, HttpMethod.GET, null, InstanceInfo.class);
195208

196209
return anEurekaHttpResponse(response.getStatusCodeValue(),
197210
response.getStatusCodeValue() == HttpStatus.OK.value() && response.hasBody() ? response.getBody()

0 commit comments

Comments
 (0)