From e33f12f5b8a37b3f2a7291a10a61c8bce6ce73e0 Mon Sep 17 00:00:00 2001 From: Norman Maurer Date: Tue, 5 Aug 2014 10:13:05 +0200 Subject: [PATCH] [#2732] HttpRequestEncoder may produce invalid uri if uri parameters are included. Motivation: If the requests contains uri parameters but not path the HttpRequestEncoder does produce an invalid uri while try to add the missing path. Modifications: Correctly handle the case of uri with paramaters but no path. Result: HttpRequestEncoder produce correct uri in all cases. --- .../codec/http/HttpRequestEncoder.java | 19 +++++++++++++++++-- .../codec/http/HttpRequestEncoderTest.java | 10 ++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/codec-http/src/main/java/io/netty/handler/codec/http/HttpRequestEncoder.java b/codec-http/src/main/java/io/netty/handler/codec/http/HttpRequestEncoder.java index 2346205b34..5ff5af9c76 100644 --- a/codec-http/src/main/java/io/netty/handler/codec/http/HttpRequestEncoder.java +++ b/codec-http/src/main/java/io/netty/handler/codec/http/HttpRequestEncoder.java @@ -26,6 +26,7 @@ import static io.netty.handler.codec.http.HttpConstants.*; */ public class HttpRequestEncoder extends HttpObjectEncoder { private static final char SLASH = '/'; + private static final char QUESTION_MARK = '?'; private static final byte[] CRLF = { CR, LF }; @Override @@ -48,8 +49,22 @@ public class HttpRequestEncoder extends HttpObjectEncoder { int start = uri.indexOf("://"); if (start != -1 && uri.charAt(0) != SLASH) { int startIndex = start + 3; - if (uri.lastIndexOf(SLASH) <= startIndex) { - uri += SLASH; + // Correctly handle query params. + // See https://github.com/netty/netty/issues/2732 + int index = uri.indexOf(QUESTION_MARK, startIndex); + if (index == -1) { + if (uri.lastIndexOf(SLASH) <= startIndex) { + uri += SLASH; + } + } else { + if (uri.lastIndexOf(SLASH, index) <= startIndex) { + int len = uri.length(); + StringBuilder sb = new StringBuilder(len + 1); + sb.append(uri, 0, index); + sb.append(SLASH); + sb.append(uri, index, len); + uri = sb.toString(); + } } } } diff --git a/codec-http/src/test/java/io/netty/handler/codec/http/HttpRequestEncoderTest.java b/codec-http/src/test/java/io/netty/handler/codec/http/HttpRequestEncoderTest.java index 6ed9b95ff6..4852fe48eb 100644 --- a/codec-http/src/test/java/io/netty/handler/codec/http/HttpRequestEncoderTest.java +++ b/codec-http/src/test/java/io/netty/handler/codec/http/HttpRequestEncoderTest.java @@ -37,6 +37,16 @@ public class HttpRequestEncoderTest { assertEquals("GET http://localhost/ HTTP/1.1\r\n", req); } + @Test + public void testUriWithoutPath2() throws Exception { + HttpRequestEncoder encoder = new HttpRequestEncoder(); + ByteBuf buffer = Unpooled.buffer(64); + encoder.encodeInitialLine(buffer, new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, + "http://localhost:9999?p1=v1")); + String req = buffer.toString(Charset.forName("US-ASCII")); + assertEquals("GET http://localhost:9999/?p1=v1 HTTP/1.1\r\n", req); + } + @Test public void testUriWithPath() throws Exception { HttpRequestEncoder encoder = new HttpRequestEncoder();