diff --git a/server/src/main/java/io/druid/server/AsyncQueryForwardingServlet.java b/server/src/main/java/io/druid/server/AsyncQueryForwardingServlet.java index bd6f5cc56ea..885b9ec841a 100644 --- a/server/src/main/java/io/druid/server/AsyncQueryForwardingServlet.java +++ b/server/src/main/java/io/druid/server/AsyncQueryForwardingServlet.java @@ -45,6 +45,7 @@ import io.druid.server.router.QueryHostFinder; import io.druid.server.router.Router; import io.druid.server.security.AuthConfig; import io.druid.server.security.Escalator; +import org.apache.http.client.utils.URIBuilder; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.client.api.Request; import org.eclipse.jetty.client.api.Response; @@ -58,10 +59,8 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.ws.rs.core.MediaType; import java.io.IOException; -import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; -import java.net.URLDecoder; import java.util.Map; import java.util.UUID; import java.util.concurrent.TimeUnit; @@ -331,15 +330,15 @@ public class AsyncQueryForwardingServlet extends AsyncProxyServlet implements Qu protected static URI makeURI(String scheme, String host, String requestURI, String rawQueryString) { try { - return new URI( - scheme, - host, - requestURI, - rawQueryString == null ? null : URLDecoder.decode(rawQueryString, "UTF-8"), - null - ); + return new URIBuilder() + .setScheme(scheme) + .setHost(host) + .setPath(requestURI) + // No need to encode-decode queryString, it is already encoded + .setQuery(rawQueryString) + .build(); } - catch (UnsupportedEncodingException | URISyntaxException e) { + catch (URISyntaxException e) { log.error(e, "Unable to rewrite URI [%s]", e.getMessage()); throw Throwables.propagate(e); } diff --git a/server/src/test/java/io/druid/server/AsyncQueryForwardingServletTest.java b/server/src/test/java/io/druid/server/AsyncQueryForwardingServletTest.java index c1c0d3b2a4e..9fcf4736fed 100644 --- a/server/src/test/java/io/druid/server/AsyncQueryForwardingServletTest.java +++ b/server/src/test/java/io/druid/server/AsyncQueryForwardingServletTest.java @@ -52,9 +52,9 @@ import io.druid.server.metrics.NoopServiceEmitter; import io.druid.server.router.QueryHostFinder; import io.druid.server.router.RendezvousHashAvaticaConnectionBalancer; import io.druid.server.security.AllowAllAuthorizer; -import io.druid.server.security.NoopEscalator; import io.druid.server.security.Authorizer; import io.druid.server.security.AuthorizerMapper; +import io.druid.server.security.NoopEscalator; import org.eclipse.jetty.client.HttpClient; import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Server; @@ -308,6 +308,19 @@ public class AsyncQueryForwardingServletTest extends BaseJettyTest new URI("http://localhost/"), AsyncQueryForwardingServlet.makeURI("http", "localhost", "/", null) ); + + // Test reWrite Encoded interval with timezone info + // decoded parameters 1900-01-01T00:00:00.000+01.00 -> 1900-01-01T00:00:00.000+01:00 + Assert.assertEquals( + new URI( + "http://localhost:1234/some/path?intervals=1900-01-01T00%3A00%3A00.000%2B01%3A00%2F3000-01-01T00%3A00%3A00.000%2B01%3A00"), + AsyncQueryForwardingServlet.makeURI( + "http", + "localhost:1234", + "/some/path", + "intervals=1900-01-01T00%3A00%3A00.000%2B01%3A00%2F3000-01-01T00%3A00%3A00.000%2B01%3A00" + ) + ); } private static class TestServer implements io.druid.client.selector.Server