Merge pull request #1297 from eiiches/SPR-15140

This commit is contained in:
Rossen Stoyanchev
2017-01-17 12:46:47 -05:00
7 changed files with 54 additions and 35 deletions

View File

@@ -60,6 +60,12 @@ public class RequestMappingIntegrationTests extends AbstractRequestMappingIntegr
assertEquals(expected, performGet("/param?name=George", new HttpHeaders(), String.class).getBody());
}
@Test // SPR-15140
public void handleWithEncodedParam() throws Exception {
String expected = "Hello ++\u00e0!";
assertEquals(expected, performGet("/param?name=%20%2B+%C3%A0", new HttpHeaders(), String.class).getBody());
}
@Test
public void longStreamResult() throws Exception {
String[] expected = {"0", "1", "2", "3", "4"};

View File

@@ -17,6 +17,7 @@
package org.springframework.http.server.reactive;
import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -26,6 +27,7 @@ import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
import org.springframework.web.util.UriUtils;
/**
* Common base class for {@link ServerHttpRequest} implementations.
@@ -94,12 +96,16 @@ public abstract class AbstractServerHttpRequest implements ServerHttpRequest {
String eq = matcher.group(2);
String value = matcher.group(3);
value = (value != null ? value : (StringUtils.hasLength(eq) ? "" : null));
queryParams.add(name, value);
queryParams.add(decodeQueryParam(name), decodeQueryParam(value));
}
}
return queryParams;
}
private static String decodeQueryParam(String value) {
return (value != null ? UriUtils.decode(value, StandardCharsets.UTF_8) : null);
}
@Override
public MultiValueMap<String, HttpCookie> getCookies() {
if (this.cookies == null) {

View File

@@ -56,20 +56,17 @@ public class ReactorServerHttpRequest extends AbstractServerHttpRequest {
private static URI initUri(HttpServerRequest channel) {
Assert.notNull("'channel' must not be null");
InetSocketAddress address = channel.remoteAddress();
return (address == null ? URI.create(channel.uri()) : getBaseUrl(address).resolve(channel.uri()));
}
private static URI getBaseUrl(InetSocketAddress address) {
try {
URI uri = new URI(channel.uri());
InetSocketAddress remoteAddress = channel.remoteAddress();
return new URI(
uri.getScheme(),
uri.getUserInfo(),
(remoteAddress != null ? remoteAddress.getHostString() : null),
(remoteAddress != null ? remoteAddress.getPort() : -1),
uri.getPath(),
uri.getQuery(),
uri.getFragment());
return new URI(null, null, address.getHostString(), address.getPort(), null, null, null);
}
catch (URISyntaxException ex) {
throw new IllegalStateException("Could not get URI: " + ex.getMessage(), ex);
// Should not happen...
throw new IllegalStateException(ex);
}
}

View File

@@ -63,25 +63,20 @@ public class RxNettyServerHttpRequest extends AbstractServerHttpRequest {
private static URI initUri(HttpServerRequest<ByteBuf> request) {
Assert.notNull("'request', request must not be null");
return StringUtils.isEmpty(request.getHostHeader()) ?
URI.create(request.getUri()) : getBaseUrl(request).resolve(request.getUri());
}
private static URI getBaseUrl(HttpServerRequest<ByteBuf> request) {
HttpHeaders headers = new HttpHeaders();
headers.add("Host", request.getHostHeader());
InetSocketAddress address = headers.getHost();
try {
URI uri = new URI(request.getUri());
InetSocketAddress remoteAddress = null;
if (!StringUtils.isEmpty(request.getHostHeader())) {
HttpHeaders headers = new HttpHeaders();
headers.add("Host", request.getHostHeader());
remoteAddress = headers.getHost();
}
return new URI(
uri.getScheme(),
uri.getUserInfo(),
(remoteAddress != null ? remoteAddress.getHostString() : null),
(remoteAddress != null ? remoteAddress.getPort() : -1),
uri.getPath(),
uri.getQuery(),
uri.getFragment());
return new URI(null, null, address.getHostString(), address.getPort(), null, null, null);
}
catch (URISyntaxException ex) {
throw new IllegalStateException("Could not get URI: " + ex.getMessage(), ex);
// Should not happen...
throw new IllegalStateException(ex);
}
}

View File

@@ -63,11 +63,19 @@ public class UndertowServerHttpRequest extends AbstractServerHttpRequest {
private static URI initUri(HttpServerExchange exchange) {
Assert.notNull(exchange, "HttpServerExchange is required.");
String requestURI = exchange.getRequestURI();
String query = exchange.getQueryString();
String requestUriAndQuery = StringUtils.isEmpty(query) ? requestURI : requestURI + "?" + query;
return (exchange.isHostIncludedInRequestURI()) ?
URI.create(requestUriAndQuery) : getBaseUri(exchange).resolve(requestUriAndQuery);
}
private static URI getBaseUri(HttpServerExchange exchange) {
try {
String query = exchange.getQueryString();
return new URI(exchange.getRequestScheme(), null,
exchange.getHostName(), exchange.getHostPort(),
exchange.getRequestURI(), StringUtils.hasText(query) ? query : null, null);
String scheme = exchange.getRequestScheme();
String host = exchange.getHostName();
int port = exchange.getHostPort();
return new URI(scheme, null, host, port, null, null, null);
}
catch (URISyntaxException ex) {
throw new IllegalStateException("Could not get URI: " + ex.getMessage(), ex);

View File

@@ -36,9 +36,9 @@ public class ServerHttpRequestIntegrationTests extends AbstractHttpHandlerIntegr
@Test
public void checkUri() throws Exception {
RestTemplate restTemplate = new RestTemplate();
RequestEntity<Void> request = RequestEntity.post(new URI("http://localhost:" + port + "/foo?param=bar")).build();
ResponseEntity<Void> response = restTemplate.exchange(request, Void.class);
URI url = new URI("http://localhost:" + port + "/foo?param=bar");
RequestEntity<Void> request = RequestEntity.post(url).build();
ResponseEntity<Void> response = new RestTemplate().exchange(request, Void.class);
assertEquals(HttpStatus.OK, response.getStatusCode());
}

View File

@@ -64,6 +64,13 @@ public class ServerHttpRequestTests {
assertEquals(Arrays.asList("1", "2"), params.get("a"));
}
@Test // SPR-15140
public void queryParamsWithEncodedValue() throws Exception {
MultiValueMap<String, String> params = createHttpRequest("/path?a=%20%2B+%C3%A0").getQueryParams();
assertEquals(1, params.size());
assertEquals(Collections.singletonList(" ++\u00e0"), params.get("a"));
}
@Test
public void queryParamsWithEmptyValue() throws Exception {
MultiValueMap<String, String> params = createHttpRequest("/path?a=").getQueryParams();