From f4de8615aa300f1fbb082b7880236e3fb460d4f8 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Tue, 30 Jan 2018 10:21:59 -0500 Subject: [PATCH] Fix encoding issue in ServerHttpRequest.mutate() Issue: SPR-16434 --- .../DefaultServerHttpRequestBuilder.java | 12 ++---- .../reactive/ServerHttpRequestTests.java | 43 +++++++++++-------- 2 files changed, 28 insertions(+), 27 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/DefaultServerHttpRequestBuilder.java b/spring-web/src/main/java/org/springframework/http/server/reactive/DefaultServerHttpRequestBuilder.java index 5166a7b4a50..442ce537604 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/DefaultServerHttpRequestBuilder.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/DefaultServerHttpRequestBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2018 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. @@ -18,7 +18,6 @@ package org.springframework.http.server.reactive; import java.net.InetSocketAddress; import java.net.URI; -import java.net.URISyntaxException; import java.util.LinkedList; import java.util.List; import java.util.Map; @@ -34,6 +33,7 @@ import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.LinkedMultiValueMap; import org.springframework.util.MultiValueMap; +import org.springframework.web.util.UriComponentsBuilder; /** * Package-private default implementation of {@link ServerHttpRequest.Builder}. @@ -139,13 +139,7 @@ class DefaultServerHttpRequestBuilder implements ServerHttpRequest.Builder { if (this.uriPath == null) { return this.uri; } - try { - return new URI(this.uri.getScheme(), this.uri.getUserInfo(), uri.getHost(), uri.getPort(), - uriPath, uri.getQuery(), uri.getFragment()); - } - catch (URISyntaxException ex) { - throw new IllegalStateException("Invalid URI path: \"" + this.uriPath + "\""); - } + return UriComponentsBuilder.fromUri(this.uri).replacePath(this.uriPath).build(true).toUri(); } private static class DefaultServerHttpRequest extends AbstractServerHttpRequest { diff --git a/spring-web/src/test/java/org/springframework/http/server/reactive/ServerHttpRequestTests.java b/spring-web/src/test/java/org/springframework/http/server/reactive/ServerHttpRequestTests.java index c8be82f1cfb..e3e30a7d901 100644 --- a/spring-web/src/test/java/org/springframework/http/server/reactive/ServerHttpRequestTests.java +++ b/spring-web/src/test/java/org/springframework/http/server/reactive/ServerHttpRequestTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2017 the original author or authors. + * Copyright 2002-2018 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. @@ -33,7 +33,7 @@ import org.springframework.mock.web.test.MockHttpServletRequest; import org.springframework.mock.web.test.MockHttpServletResponse; import org.springframework.util.MultiValueMap; -import static org.junit.Assert.assertEquals; +import static org.junit.Assert.*; /** * Unit tests for {@link AbstractServerHttpRequest}. @@ -85,26 +85,33 @@ public class ServerHttpRequestTests { assertEquals(Collections.singletonList(null), params.get("a")); } + @Test // SPR-16434 + public void mutatePathWithEncodedQueryParams() throws Exception { + ServerHttpRequest request = createHttpRequest("/path?name=%E6%89%8E%E6%A0%B9") + .mutate().path("/mutatedPath").build(); + assertEquals("/mutatedPath", request.getURI().getRawPath()); + assertEquals("name=%E6%89%8E%E6%A0%B9", request.getURI().getRawQuery()); + } + + private ServerHttpRequest createHttpRequest(String path) throws Exception { - HttpServletRequest request = new MockHttpServletRequest("GET", path) { - @Override - public ServletInputStream getInputStream() { - return new TestServletInputStream(); - } - }; + HttpServletRequest request = createEmptyBodyHttpServletRequest(path); AsyncContext asyncContext = new MockAsyncContext(request, new MockHttpServletResponse()); return new ServletServerHttpRequest(request, asyncContext, "", new DefaultDataBufferFactory(), 1024); } - private static class TestServletInputStream extends DelegatingServletInputStream { - - public TestServletInputStream() { - super(new ByteArrayInputStream(new byte[0])); - } - - @Override - public void setReadListener(ReadListener readListener) { - // Ignore - } + private HttpServletRequest createEmptyBodyHttpServletRequest(String path) { + return new MockHttpServletRequest("GET", path) { + @Override + public ServletInputStream getInputStream() { + return new DelegatingServletInputStream(new ByteArrayInputStream(new byte[0])) { + @Override + public void setReadListener(ReadListener readListener) { + // Ignore + } + }; + } + }; } + }