HADOOP-11350. The size of header buffer of HttpServer is too small when HTTPS is enabled. Contributed by Benoy Antony.
Project: http://git-wip-us.apache.org/repos/asf/hadoop/repo Commit: http://git-wip-us.apache.org/repos/asf/hadoop/commit/e4c94296 Tree: http://git-wip-us.apache.org/repos/asf/hadoop/tree/e4c94296 Diff: http://git-wip-us.apache.org/repos/asf/hadoop/diff/e4c94296 Branch: refs/heads/HDFS-EC Commit: e4c94296855c4ab8d70d1ada5723cb3c62b3c4d2 Parents: 93b7e86 Author: Haohui Mai <whe...@apache.org> Authored: Thu Jan 15 16:17:30 2015 -0800 Committer: Zhe Zhang <z...@apache.org> Committed: Tue Jan 20 09:43:10 2015 -0800 ---------------------------------------------------------------------- hadoop-common-project/hadoop-common/CHANGES.txt | 3 ++ .../org/apache/hadoop/http/HttpServer2.java | 1 + .../hadoop/http/HttpServerFunctionalTest.java | 32 ++++++++++++++++++++ .../org/apache/hadoop/http/TestHttpServer.java | 24 +-------------- .../apache/hadoop/http/TestSSLHttpServer.java | 15 ++++++++- 5 files changed, 51 insertions(+), 24 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hadoop/blob/e4c94296/hadoop-common-project/hadoop-common/CHANGES.txt ---------------------------------------------------------------------- diff --git a/hadoop-common-project/hadoop-common/CHANGES.txt b/hadoop-common-project/hadoop-common/CHANGES.txt index 5cce74b..e1a6800 100644 --- a/hadoop-common-project/hadoop-common/CHANGES.txt +++ b/hadoop-common-project/hadoop-common/CHANGES.txt @@ -711,6 +711,9 @@ Release 2.7.0 - UNRELEASED HADOOP-11462. TestSocketIOWithTimeout needs change for PowerPC platform. (Ayappan via cnauroth) + HADOOP-11350. The size of header buffer of HttpServer is too small when + HTTPS is enabled. (Benoy Antony via wheat9) + Release 2.6.0 - 2014-11-18 INCOMPATIBLE CHANGES http://git-wip-us.apache.org/repos/asf/hadoop/blob/e4c94296/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer2.java ---------------------------------------------------------------------- diff --git a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer2.java b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer2.java index 80e4005..80831e9 100644 --- a/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer2.java +++ b/hadoop-common-project/hadoop-common/src/main/java/org/apache/hadoop/http/HttpServer2.java @@ -279,6 +279,7 @@ public final class HttpServer2 implements FilterContainer { listener = HttpServer2.createDefaultChannelConnector(); } else if ("https".equals(scheme)) { SslSocketConnector c = new SslSocketConnectorSecure(); + c.setHeaderBufferSize(1024*64); c.setNeedClientAuth(needsClientAuth); c.setKeyPassword(keyPassword); http://git-wip-us.apache.org/repos/asf/hadoop/blob/e4c94296/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/HttpServerFunctionalTest.java ---------------------------------------------------------------------- diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/HttpServerFunctionalTest.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/HttpServerFunctionalTest.java index ecf2d0f..4a4de41 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/HttpServerFunctionalTest.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/HttpServerFunctionalTest.java @@ -28,15 +28,32 @@ import org.apache.hadoop.http.HttpServer2.Builder; import java.io.File; import java.io.IOException; import java.io.InputStream; +import java.net.HttpURLConnection; import java.net.URI; import java.net.URL; import java.net.MalformedURLException; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + /** * This is a base class for functional tests of the {@link HttpServer2}. * The methods are static for other classes to import statically. */ public class HttpServerFunctionalTest extends Assert { + @SuppressWarnings("serial") + public static class LongHeaderServlet extends HttpServlet { + @Override + public void doGet(HttpServletRequest request, + HttpServletResponse response + ) throws ServletException, IOException { + Assert.assertEquals(63 * 1024, request.getHeader("longheader").length()); + response.setStatus(HttpServletResponse.SC_OK); + } + } + /** JVM property for the webapp test dir : {@value} */ public static final String TEST_BUILD_WEBAPPS = "test.build.webapps"; /** expected location of the test.build.webapps dir: {@value} */ @@ -44,6 +61,7 @@ public class HttpServerFunctionalTest extends Assert { /** name of the test webapp: {@value} */ private static final String TEST = "test"; + protected static URL baseUrl; /** * Create but do not start the test webapp server. The test webapp dir is @@ -227,4 +245,18 @@ public class HttpServerFunctionalTest extends Assert { } return out.toString(); } + + /** + * Test that verifies headers can be up to 64K long. + * The test adds a 63K header leaving 1K for other headers. + * This is because the header buffer setting is for ALL headers, + * names and values included. */ + protected void testLongHeader(HttpURLConnection conn) throws IOException { + StringBuilder sb = new StringBuilder(); + for (int i = 0 ; i < 63 * 1024; i++) { + sb.append("a"); + } + conn.setRequestProperty("longheader", sb.toString()); + assertEquals(HttpURLConnection.HTTP_OK, conn.getResponseCode()); + } } http://git-wip-us.apache.org/repos/asf/hadoop/blob/e4c94296/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpServer.java ---------------------------------------------------------------------- diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpServer.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpServer.java index a2034f3..5b202da 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpServer.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestHttpServer.java @@ -67,7 +67,6 @@ import java.util.concurrent.Executors; public class TestHttpServer extends HttpServerFunctionalTest { static final Log LOG = LogFactory.getLog(TestHttpServer.class); private static HttpServer2 server; - private static URL baseUrl; private static final int MAX_THREADS = 10; @SuppressWarnings("serial") @@ -121,17 +120,6 @@ public class TestHttpServer extends HttpServerFunctionalTest { } @SuppressWarnings("serial") - public static class LongHeaderServlet extends HttpServlet { - @Override - public void doGet(HttpServletRequest request, - HttpServletResponse response - ) throws ServletException, IOException { - Assert.assertEquals(63 * 1024, request.getHeader("longheader").length()); - response.setStatus(HttpServletResponse.SC_OK); - } - } - - @SuppressWarnings("serial") public static class HtmlContentServlet extends HttpServlet { @Override public void doGet(HttpServletRequest request, @@ -210,20 +198,10 @@ public class TestHttpServer extends HttpServerFunctionalTest { readOutput(new URL(baseUrl, "/echomap?a=b&c<=d&a=>"))); } - /** - * Test that verifies headers can be up to 64K long. - * The test adds a 63K header leaving 1K for other headers. - * This is because the header buffer setting is for ALL headers, - * names and values included. */ @Test public void testLongHeader() throws Exception { URL url = new URL(baseUrl, "/longheader"); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); - StringBuilder sb = new StringBuilder(); - for (int i = 0 ; i < 63 * 1024; i++) { - sb.append("a"); - } - conn.setRequestProperty("longheader", sb.toString()); - assertEquals(HttpURLConnection.HTTP_OK, conn.getResponseCode()); + testLongHeader(conn); } @Test public void testContentTypes() throws Exception { http://git-wip-us.apache.org/repos/asf/hadoop/blob/e4c94296/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestSSLHttpServer.java ---------------------------------------------------------------------- diff --git a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestSSLHttpServer.java b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestSSLHttpServer.java index 3d5d8b6..70fea87 100644 --- a/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestSSLHttpServer.java +++ b/hadoop-common-project/hadoop-common/src/test/java/org/apache/hadoop/http/TestSSLHttpServer.java @@ -49,7 +49,6 @@ public class TestSSLHttpServer extends HttpServerFunctionalTest { private static final Log LOG = LogFactory.getLog(TestSSLHttpServer.class); private static Configuration conf; private static HttpServer2 server; - private static URL baseUrl; private static String keystoresDir; private static String sslConfDir; private static SSLFactory clientSslFactory; @@ -85,6 +84,7 @@ public class TestSSLHttpServer extends HttpServerFunctionalTest { sslConf.get("ssl.server.truststore.password"), sslConf.get("ssl.server.truststore.type", "jks")).build(); server.addServlet("echo", "/echo", TestHttpServer.EchoServlet.class); + server.addServlet("longheader", "/longheader", LongHeaderServlet.class); server.start(); baseUrl = new URL("https://" + NetUtils.getHostPortString(server.getConnectorAddress(0))); @@ -106,6 +106,19 @@ public class TestSSLHttpServer extends HttpServerFunctionalTest { "/echo?a=b&c<=d&e=>"))); } + /** + * Test that verifies headers can be up to 64K long. + * The test adds a 63K header leaving 1K for other headers. + * This is because the header buffer setting is for ALL headers, + * names and values included. */ + @Test + public void testLongHeader() throws Exception { + URL url = new URL(baseUrl, "/longheader"); + HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); + conn.setSSLSocketFactory(clientSslFactory.createSSLSocketFactory()); + testLongHeader(conn); + } + private static String readOut(URL url) throws Exception { HttpsURLConnection conn = (HttpsURLConnection) url.openConnection(); conn.setSSLSocketFactory(clientSslFactory.createSSLSocketFactory());